初探云原生高性能网关篇1
【初探云原生】高性能网关篇(1)
【初探云原生】高性能网关篇(1)
什么是网关
首先要解释的是为什么我们需要一层网关的逻辑呢?我们的后端大多是为移动端或者前端展示提供支撑,对于入口流量有些通用的痛点,那在架构层面就更倾向于增加一层网关来解决公共的问题。一般在系统设计时候也会区分流量网关和业务网关,本文主要关注更加技术层面的流量网关。流量网关一般提供着流量路由、负载均衡、弹性设计(包括了超时、重试、流控、熔断等等)、安全认证等能力。
网关的选型
业界常见的网关类型包括着Nginx、Zuul/Zuul2、Spring-Cloud-Gateway、Kong、APISIX、Envoy等解决方案,其中Envoy、Kong、APISIX更倾向于支持云原生方式。
网关 | 语言 | 特征 | 备注 |
---|---|---|---|
Envoy | C++ | 高性能,可编程,与Servicemesh集成 | 云原生 |
Kong | OpenResty/Lua | 高性能,可编程API | 云原生 |
Nginx | C/Lua | 高性能,成熟稳定 | 传统 |
Zuul/Zuul2 | Java | 成熟,门槛低 | 传统 |
Spring-Cloud-Gateway | Java | 异步,配置灵便 | 传统 |
从最新的CNCF Landscape可以看到越来越多的网关解决方案涌现在云原生的版图上。从github的热度上,可以看出主流倾向的方案还是上面提到的Kong和APISIX。
逐个击破
Enovy网关
Envoy 是一个为云原生应用设计的开源边缘与服务代理,是云原生计算基金会(CNCF)第三个毕业的项目。其主要特性如下:
- 基于现代 C++ 开发的 L4/L7 高性能代理。
- 透明代理。
- 流量管理。支持路由、流量复制、分流等功能。
- 治理特性。支持健康检查、熔断、限流、超时、重试、故障注入。
- 多协议支持。支持 HTTP/1.1,HTTP/2,GRPC,WebSocket 等协议代理与治理。
- 负载均衡。加权轮询、加权最少请求、Ring hash、Maglev、随机等算法支持。支持区域感知路由、故障转移等特性。
- 动态配置 API。提供健壮的管控代理行为的接口,实现 Envoy 动态配置热更新。
- 可观察性设计。提供七层流量高可观察性,原生支持分布式追踪。
- 支持热重启。可实现 Envoy 的无缝升级。
- 自定义插件能力。Lua 与多语言扩展沙箱 WebAssembly。
Envoy 本身的架构如下。Envoy 本身可以与多个控制面结合,其中最有名的也就是云原生服务网格的 Istio。
对于云原生网关,Ingress 成为 K8s 生态的网关标准,促使流量网关和业务网关,合二为一。基于 Ingress 规范的实现主要分为基于 Nginx 和基于 Envoy 两大阵营,基于 Nginx 的 Nginx Ingress Controller 是目前大多数 K8s 集群的选择,基于 Envoy 的实现作为后起之秀,大有赶超之势。Nginx Ingress Controller 控制面(Go 实现的 Controller)和数据面(Nginx)进程混跑在一个容器内,高负载下,数据面进程和控制面进程出现了 CPU 抢占。其中控制面进程负责了健康检查和监控指标采集,因为没有足够的 CPU 导致请求积压引起 OOM 以及健康检查超时。这种情况是极危险的,会在高负载下引发网关的雪崩效应,对业务造成严重影响。Envoy 云原生网关使用了数据面和控制面隔离的架构,在架构上具备可靠性优势。
Kong
云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。因此,云原生网关很重要的特性之一,就是能够快速集成到持续发布的云原生环境中。
Kong基于OpenResty开发,也是流量层网关, 是一个云原生、快速、可扩展、分布式的Api 网关。继承了OpenResty的高性能、易扩展性等特点。Kong通过简单的增加机器节点,可以很容易的水平扩展。同时功能插件化,可通过插件来扩展其能力。而且Kong 可以在 Kubernetes 或物理环境上运行,符合云原生网关的要求。
KONG本身提供包括 HTTP 基本认证、密钥认证、CORS、TCP、UDP、文件日志、API请求限流、请求转发及 NGINX 监控等基本功能。目前,Kong 在 Mashape 管理了超过 15,000 个 API,为 200,000 开发者提供了每月数十亿的请求支持。
Nginx
Nginx是一个高性能的HTTP和反向代理服务器。Nginx一方面可以做反向代理,另外一方面可以做静态资源服务器,接口使用Lua动态语言可以完成灵活的定制功能。
下图为Nginx的整体架构。Nginx 在启动后,会有一个 Master 进程和多个 Worker 进程,Master 进程和 Worker 进程之间是通过进程间通信进行交互的,如图所示。Worker 工作进程的阻塞点是在像 select()、epoll_wait() 等这样的 I/O 多路复用函数调用处,以等待发生数据可读 / 写事件。Nginx 采用了异步非阻塞的方式来处理请求,也就是说,Nginx 是可以同时处理成千上万个请求的。
Zuul/Zuul2
Zuul是所有从设备和web站点到Netflix流媒体应用程序后端请求的前门。作为一个边缘服务应用程序,Zuul被构建来支持动态路由、监视、弹性和安全性。它还可以根据需要将请求路由到多个Amazon自动伸缩组。
zuul 网关架构整体如下图。网关过滤器运行时模块本身是一个http servlet,当请求过来首先交给zuul servlet, 再由 servlet 将请求交给责任链模式的zuul filter runner。请求会依次经过前置路由过滤器, 路由过滤器, 和后置路由过滤器。经过过滤以后, 请求会以response的形式响应给客户端。在经过整个链路时,为了实现共享上下文信息,则有了Request Context 组件。
zuul 本身的生命周期如下。
1、请求先经过前置过滤器pre filter.
2、进入routing filter路由过滤器,routing filter路由过滤器是真正的向后台服务发起请求, 接收响应的过滤器
3、经过routing filter路由过滤器,最后会传递过post filter 后置过滤器,进行一些后续的处理,这时候已经拿到响应了, 然后在返回给客户端.
4、在发生错误异常时,都会通过error filter进行统一的异常处理. error filter错误过滤器会发送给post filter,也是以响应的方式发回给客户端.
Zuul2 在处理IO模型上进行了升级,异步取代同步,解决了作为网关的核心痛点网关阻塞问题。从架构能看出属于一脉相承,有相通类似的地方。技术上将北向Servlet 替换成 Netty,南向用Netty Client代替Http Client。
Spring-Cloud-Gateway
SpringCloud Gateway 是 Spring Cloud 的一个全新项目。为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
除了前后的连接层,网关内部主要包含如下组件:
1、Route(路由):路由是由路由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由,目标URI会被访问。
2、Predicate(断言):这是一个java 8的Predicate,可以使用它来匹配来自HTTP请求的任何内容,如:请求头和请求参数。
3、Filter(过滤器):指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者后对请求进行修改。