vlambda博客
学习文章列表

API网关的技术形态和发展趋势

“Any problem in computer science can be solved by anther layer of indirection.”  — David Wheeler


在软件架构设计中很多都采用“层”的结构,所以有这样一句名言:“计算机领域的任何问题都可以通过增加一个间接的中间层来解决”。API网关便是这样一个中间层,无论是早期银行证券系统的前置机,还是随着微服务架构模式发展而演化出来的API网关,它都是作为API访问的统一接入的中间层。今天我们从以下四点来聊一聊API网关:

  • 微服务典的四层架构

  • API网关模式
  • 常见的开源API网关
  • 网关在容器技术和K8S主导的云原生时代将如何演进

1. 微服务经典的四层架构

单体应用中有一个典型的MVC分层技术,把系统分为数据层、展示层和业务逻辑层,在这种模式下我们比较关注应用自身。而到微服务时期,每个微服务除了数据和业务逻辑之外,往往要依赖下游服务的API,同时自身也会提供API给上游服务,微服务之间相互协作提供整体的系统能力。此时,除了微服务本身之外更加关注整个上下游,为了统一API接入和避免公共能力的重复建设,设计了网关路由层;为了更加解耦,不至于微服务牵一发而动全身,又独立出一个BFF层(Backend For Front)。这就是典型的四层架构:前端层、网关层、BFF层、微服务层。借用netflix的系统架构为例来说明一下,早期netflix四层架构如下图:API网关的技术形态和发展趋势

用户体验层 :支持各种不同的前端设备,给用户良好的使用体验。
网关路由层 :使用zuul网关作为服务路由层,同时兼具安全、监控、熔断、限流等横切功能。zuul网关无状态集群部署,前置AWS ELB 做负载均衡。
边界API层 :服务剪裁聚合层,也就是BFF层,当然在netflix内部并不叫BFF,而是称其为边缘服务层(Edge Service Layer),将后端微服务适配到不同的前端体验。
微服务层 :核心领域服务,也称为中间层(MIddle Tier)服务。

随着业务的更加复杂,边界API层一方面随着微服务层的变动而频繁修改,给开发测试带来巨大的工作量,于是独立出一层隔离变化。

API网关的技术形态和发展趋势

无论是四层还是五层,netflix服务入口流量都是由zuul一夫当关,作为边缘网关,将外部流量调度到内部服务,俗称南北流量调度。当然,边缘网关作为外部流量进入内部服务的第一道“关卡”,天然适合承载安全认证、流量控制等通用功能,这也就引出了另一个话题:API网关模式!

2. API网关模式

API网关是定义在外部服务进入内部服务入口处的一种服务,类似于面向对象设计的外观模式,它封装了应用程序的内部架构,为客户端提供统一的API,下面示意图展示了客户端、API网关和内部服务之间的关系。
API网关的技术形态和发展趋势
作为入口层,API网关在架构设计中占尽“地缘”优势。一方面,就像城堡的大门,访客的身份认证、权限控制、路线引导(路由)、人流控制(排队机制/关闭通道等)、访问记录等功能;另一方面,后端API需要的通用功能比如重试机制、熔断、限流、降级等也可以放到这一层,避免各个微服务重复建设。下表大概罗列一下API网关所承载的功能。当然,表格并没有完全覆盖API网关的全部功能,也不是说一个API网关必须具备罗列的所有功能才行。在具体场景中,根据需求来选择和取舍。
基础功能

其他功能

  • 请求路由(静态/动态)

  • 路径重写

  • 协议转换

  • API聚合

  • 请求日志

  • 缓存

  • 证书/加解密处理

  • 身份验证

  • 访问授权

  • 速率限制

  • 指标收集

  • 负载均衡

  • 服务降级

  • 服务重试

  • 安全策略(黑白名单等)

然而,在一个足够复杂的业务场景里,API网关所承载的功能还不止上表所罗列的范围。随着业务发展和系统演进,API网关系统变得越来越复杂,此时API网关进一步拆分, 根据功能属性和业务耦合性拆分为流量网关和业务网关(也叫微服务网关)。
  • 流量网关:跟具体的后端业务服务完全无关,比如安全策略、全局性流控策略、流量分发策略等,其功能跟 Web 应用防火墙(WAF)非常类似,可基于 Nginx/OpenResty 的 ngx_lua 模块开发。

  • 业务网关:与后端服务和业务有一定关联性,并且一般被直接部署在业务服务的前面。业务网关一般部署在流量网关之后,业务系统之前,比流量网关更靠近服务。我们大部分情况下说的API网关,狭义上指的是业务网关。并且如果系统的规模不大,我们也会将两者合二为一,使用一个网关来理所有的工作。

随着这种经典的双层模型在越来越多的公司和业务领域发挥出重要的作用,也促使越来越多的成熟方案开源回馈社区,如果只是想简单使用可以拿来主义,若是想完全把控或者有自己业务诉求可以选择稳定可靠方便扩展的来进一步研发。
3. 常见的开源API网关

如果百度谷歌一下的话会发现可选择的API网关灰常多,按语言分类常见的开源网关大概有五大类:

语 言

开源网关

Nginx + Lua
OpenResty, Kong, Orange, ABTesting gateway等
Java
Zuul/Zuul2、Spring Cloud Gateway、Kaazing KWG、gravitee、Dromara soul等
Go
Janus、fagongzi、Grpc-gateway,Gloo,istio gateway等
.net
Ocelot
nodejs
Express Gateway、Micro Gateway
按照目前成熟度和使用广泛程度来划分的话,主流的有这样四个:
  • OpenResty

  • Kong

  • zuul

  • Spring Cloud Gateway

3.1 Openresty

OpenResty 基于 Nginx,集成了 Lua 语言和 Lua 的各种工具库,可用的第三方模块,这样我们就在 Nginx 既有的高效 HTTP 处理的基础上,同时获得了 Lua 提供的动态扩展能力。想了解更多详细信息可见其项目地址:http://openresty.org
3.2 Kong

API网关的技术形态和发展趋势

3.3 Zuul

API网关的技术形态和发展趋势

Zuul 2.x 最大的改进就是基于 Netty Server 实现了异步 IO 来接入请求,同时基于 Netty Client 实现了到后端业务服务 API 的请求。这样就可以实现更高的性能、更低的延迟。此外也调整了 filter 类型,将原来的三个核心 filter 显式命名为:Inbound Filter、Endpoint Filter 和 Outbound Filter。

API网关的技术形态和发展趋势

3.4 Spring Cloud Gateway

Spring Cloud Gateway 基于 Java 8、Spring 5.0、Spring Boot 2.0、Project Reactor,是一个构建在spring cloud生态系统之上的API网关。一般认为是 Zuul 1.x 的升级版和代替品,它基于 Netty 异步 IO实现了一个简单、比 Zuul 1.x 更高效的、与 Spring Cloud 紧密配合的 API 网关。Spring Cloud Gateway 里明确的区分了 Router 和 Filter,它旨在提供一种简单有效的方法来路由到API,内置了很多开箱即用的横切功能,包括路由、断路器、限流、黑白名单、负载均衡、auth等, 并且都可以通过 SpringBoot 配置或者手工编码链式调用来使用。

API网关的技术形态和发展趋势


3.5 如何选择?

如何选择上面四个成熟的开源网关呢?脱离场景的情况下其实无法做正确选择的,我们要具体分析。
  1. kong 性能优秀,非常适合做流量网关,同样是基于nginx和lua,Kong在openresty基础上做了很多扩展,对于 service、route、upstream、consumer、plugins 的抽象,也是自研网关值得借鉴的。但是,对于复杂系统,不建议业务网关用 Kong,或者更明确的说是不建议在 Java 技术栈的系统深度定制 Kong 或 OpenResty,主要是工程性方面的考虑。毕竟维护lua脚本的工作量和成本不低

  2. Spring Cloud Gateway对于 Java 技术栈来说比较方便,可以复用业务系统的一些组件。Lua 不方便,不光是语言的问题,更是复用基础设施的问题。另外,对于网关系统来说,性能不是差一个数量级,问题不大,多加 2 台机器就可以搞定。目前来看 Zuul2 的坑还是比较多的,因此作为java技术栈,比较建议使用 Spring Cloud Gateway 作为基础骨架。

4. 云原生时代网关将如何演进
在容器技术和k8s主导的云原生时代,k8s已然是云OS,在这个云原生生态里也衍生出了一些新兴的网关方案。
4.1 Ingress
首先要从k8s ingress讲起,ingress作为一个k8s的一个资源,本身就是一个具备7层反向代理的组件,作为集群流量的入口,扮演边缘路由器(edge route)的角色。换句话说,ingress可以把进入集群的请求转发的集群内对应的服务上。所以,配合一个类似nginx的反向代理或者LB就可以完成把外部流量转发到内部服务的网关功能。这部分详细的解释和demo会在后续的文章里逐步展开,本文只做简单介绍。在云原生第一篇中曾经介绍过K8S的CRD工作模式,一个资源必然会有一个controller来管理,ingress资源是有IngressController来管理的。它实时感知Ingress路由规则集合的变化,再与Api Server交互,获取Service、Pod在集群中的 IP等信息,然后发送给反向代理web服务器,刷新其路由配置信息,这就是它的服务发现机制。下面是一个工作原理示意图:

API网关的技术形态和发展趋势


4.2 Nginx Ingress

把上面Ingress原理图中的反向代理换成nginx,再配合Nginx Ingress Controller来动态调整配置便是Nginx Ingress,其工作原理可以简单描述为:Nginx ingress控制器通过和APIServer交互,动态感知集群中ingress规则变化,然后读取它并生成的Nginx配置写入nginx的/etc/nginx.conf文件中,reload使配置生效。以此达到域名分配置和动态更新的问题。下面是一个网上找的示意图,图中右下角只画了iptable来规则来选择pod并不完全,但不妨碍我们理解nginx ingress的工作原理。详细的信息可以从这里了解:https://kubernetes.github.io/ingress-nginx/

API网关的技术形态和发展趋势

4.3 Traefik
Traefik是一个用Golang开发的轻量级的Http反向代理和负载均衡器,作为后起之秀,他天然拥抱kubernete。使用Traefik不用创建Ingress controller对象,它直接k8s的Api Server通信,实时感知集群中Ingress定义的路由规则集合和后端Service/Pod的变化,自动热更新Traefik后端配置。同时还提供了友好的控制面板和监控界面,不仅可以方便地查看Traefik根据Ingress生成的路由配置信息,还可以查看统计的一些性能指标数据,如:总响应时间、平均响应时间、不同的响应码返回的总次数等。另外,Traefik还支持丰富的annotations配置,可配置众多出色的特性,例如:自动熔断、负载均衡策略、黑名单、白名单。
4.4 Istio Ingress gateway
我们知道envoy作为istio的数据面有两种工作模式:
  1. 作为中心代理,代理集群的南北流量,也就是入口流量,负责流量分发、流量治理类的工作。这种模式下,envoy一般就是负载均衡设备或者api网关的基础数据面,在非istio场景里比较有代表的ambassador, gloo。

  2. 作为业务进程的sidecar。当有业务请求访问业务的时候,流量会劫持到sidecar envoy中,之后再转发到业务进程。当业务访问其他业务时,请求流量会被拦截到sidecar envoy中,再被转发到目标服务。

Istio Ingress Gateway是Envoy第一种模式的代理封装,在service mesh环境中也是一个不错的选择。使用Istio Gateway(Envoy)做南北流量调度,同时使用sidecar(Envoy)做东西流量治理。下面是一个示意图:

选择这种方案的一个好处是统一到envoy前提是你的基础设施底座已经具备服务网格这个条件。另一个好处,如果你们微服务场景下使用了不同的语言和技术栈去实现特定的服务,这种方案可以做到技术栈解耦。但用istio ingress gateway做网关也有局限性:它比较适合做基础的流量控制,比如限流/重试/熔断等,而和业务相关的比如身份认证、鉴权等比较难做。当然如果团队有这个技术栈,能做基于envoy(c++技术栈)的扩展研发,或许可以定制一些插件。否则通用的基础流量调度能力放在envoy,业务网关还需要选择另一个方案,两种方案并存会增加不少复杂性。

4.5 新的动向

除了上面介绍的几个云原生环境里基于K8S的网关方案之外,还有不少其他方案,比如ambassador, gloo,其实前文写到的kong也是。业界有不少在K8S集群基于服务网格的网关探索和实践的案例,比如蚂蚁无线网关基于MOSN的mesh化改造,再比如网易基于envoy的网关演进等等。

如果说上面一些方案只是技术底座的不同,并没有改变网关的属性和功能定义,也没有改变传统的流量网关和微服务网关的双层模型来分别做北流量和东西流量的调度。那么新的一种探索趋势的确是东西南北流量调度以及服务治理合二为一,以此减低资源使用和运维成本下图网上找的合二为一的网关示意图,这大概也许就是对云原生网关的最新定义

理念和想法都是很美好的,对于很多正在往k8s平台走的公司来说也许亲自打造还有不小距离。但完成云原生改造的希望也许也并不遥远,不久前阿里云就上线了这样一款云原生网关,对于云上的用户来说有兴趣可以调研一下是否可以直接引入使用。相信其他云厂商也都会逐步推出类似的技术产品。而对于我们技术同学来说,学习远没有止境。