1. API网关解决的问题
在微服务的架构下,API 网关是一个常见的架构设计模式。以下是微服务中常见的问题,需要引入 API 网关来协助解决。
- 微服务提供的 API 的粒度通常与客户端所需的粒度不同。微服务通常提供细粒度的 API,这意味着客户端需要与多个服务进行交互。例如产品详细信息页面需要从多个服务中获取数据。
- 不同的客户端需要不同的数据。例如产品详细信息页面PC端版本通常比移动版本更为详尽。
- 对于不同类型的客户端,网络性能是不同的。例如移动网络通常要慢得多并且具有更高的延迟。PC端 Web 应用程序可以向后端服务发出多个请求,而不会影响用户体验,而移动客户端只能提供几个请求。
- 微服务实例数量及其位置(主机+端口)动态变化
- 服务划分会随着时间的推移而变化,应该对客户端隐藏
- 服务可能会使用多种协议,其中一些协议可能对网络不友好
2. API网关提供的主要功能
常见的 API 网关主要提供以下的功能:
- 反向代理和路由 - 这是大多数项目采用网关最主要的原因。为所有客户端提供单一入口,并隐藏内部服务部署的细节。
- 负载均衡 - 网关可以将单个传入的请求路由到多个后端目的地。
- 身份验证和授权 - 进行身份验证并仅允许可信客户端访问 API,并且还能够使用类似 RBA C等方式来授权。
- IP 列表白名单/黑名单 - 允许或阻止某些 IP 地址通过。
- 性能分析 - 提供一种记录与 API 调用相关的使用和其他有用度量的方法。
- 限速和流控 - 控制 API 调用的能力。
- 请求变形 - 在进一步转发之前,能够在转发之前转换请求和响应(包括 Header 和 Body)。
- 版本控制 - 同时使用不同版本的 API 选项或可能以金丝雀发布或蓝/绿部署的形式提供慢速推出 API
- 断路器 - 微服务架构模式有用,以避免使用中断
- 多协议支持 WebSocket/GRPC
- 缓存 - 减少网络带宽和往返时间消耗,如果可以缓存频繁要求的数据,则可以提高性能和响应时间
- API 文档 - 如果计划将 API 暴露给组织以外的开发人员,那么必须考虑使用 API 文档,例如 Swagger 或 OpenAPI。
3. 常用的API网关
3.1. Nginx
Nginx 是异步框架的网页服务器,也可以用作反向代理、负载平衡器和 HTTP 缓存。该软件由伊戈尔·赛索耶夫创建并于 2004 年首次公开发布。2011 年成立同名公司以提供支持。2019 年 3 月 11 日,Nginx 公司被 F5 Networks 以 6.7 亿美元收购。
Nginx 有以下的特点:
- 由 C 编写,占用的资源和内存低,性能高。
- 单进程多线程,当启动 nginx 服务器,会生成一个 master 进程,master 进程会 fork 出多个 worker 进程,由 worker 线程处理客户端的请求。
- 支持反向代理,支持 7 层负载均衡(拓展负载均衡的好处)。
- 高并发,nginx 是异步非阻塞型处理请求,采用的 epoll 和 queue 模式
- 处理静态文件速度快
- 高度模块化,配置简单。社区活跃,各种高性能模块出品迅速。
如上图所示,Nginx 主要由 Master,Worker 和 Proxy Cache 三个部分组成。
- Master 主控:NGINX 遵循主从架构。它将根据客户的要求为 Worker 分配工作。将工作分配给 Worker 后,Master 将寻找客户的下一个请求,因为它不会等待 Worker 的响应。一旦响应来自 Worker,Master 就会将响应发送给客户端
- Worker 工作单元:Worker 是 NGINX 架构中的 Slave。每个工作单元可以单线程方式一次处理 1000 个以上的请求。一旦处理完成,响应将被发送到主服务器。单线程将通过在相同的内存空间而不是不同的内存空间上工作来节省 RAM 和 ROM 的大小。多线程将在不同的内存空间上工作。
- Cache 缓存:Nginx 缓存用于通过从缓存而不是从服务器获取来非常快速地呈现页面。在第一个页面请求时,页面将被存储在高速缓存中。
3.2. Kong
Kong 是基于 NGINX 和 OpenResty 的开源 API 网关。
Kong 的总体基础结构由三个主要部分组成:NGINX 提供协议实现和工作进程管理,OpenResty 提供 Lua 集成并挂钩到 NGINX 的请求处理阶段,而 Kong 本身利用这些挂钩来路由和转换请求。数据库支持 Cassandra 或 Postgres 存储所有配置。
Kong 附带各种插件,提供访问控制,安全性,缓存和文档等功能。它还允许使用 Lua 语言编写和使用自定义插件。Kong 也可以部署为 Kubernetes Ingress 并支持 GRPC 和 WebSockets 代理。
OpenResty 是一个软件套件,捆绑了 NGINX,一组模块,LuaJIT 和一组 Lua 库。其中最主要的是 ngx_http_lua_module一个NGINX 模块,该模块嵌入 Lua 并为大多数 NGINX 请求阶段提供 Lua 等效项。这有效地允许在 Lua 中开发 NGINX 模块,同时保持高性能(LuaJIT 相当快),并且 Kong 用它来提供其核心配置管理和插件管理基础结构。
3.3. APISIX
Apache APISIX 是一个动态、实时、高性能的 API 网关, 提供负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。
APISIX 于 2019 年 4 月由中国的支流科技创建,于 6 月开源,并于同年 10 月进入Apache孵化器。支流科技对应的商业化产品的名字叫 API7 :)。APISIX 旨在处理大量请求,并具有较低的二次开发门槛。
APISIX 的主要功能和特点有:
- 云原生设计,轻巧且易于容器化
- 集成了统计和监视组件,例如 Prometheus,Apache Skywalking 和 Zipkin。
- 支持 gRPC,Dubbo,WebSocket,MQTT 等代理协议,以及从 HTTP 到 gRPC 的协议转码,以适应各种情况
- 担当 OpenID 依赖方的角色,与 Auth0,Okta 和其他身份验证提供程序的服务连接
- 通过在运行时动态执行用户功能来支持无服务器,从而使网关的边缘节点更加灵活
- 支持插件热加载
- 不锁定用户,支持混合云部署架构
- 网关节点无状态,可以灵活扩展
从这个角度来看,API 网关可以替代 Nginx 来处理南北流量,也可以扮演 Istio 控制平面和 Envoy 数据平面的角色来处理东西向流量。
APISIX 的架构如下图所示:
3.4. Tyk
Tyk 是一款基于 Golang 和 Redis 构建的开源 API 网关。它于 2014 年创建,比 AWS 的 API 网关即服务功能早。Tyk 用 Golang 编写,并使用 Golang 自己的 HTTP 服务器。
Tyk 支持不同的运行方式:云,混合(在自己的基础架构中为 GW)和本地。
图片
Tyk 由 3 个组件组成:
- 网关:处理所有应用流量的代理。
- 仪表板:可以从中管理 Tyk,显示指标和组织 API 的界面。
- Pump:负责持久保存指标数据,并将其导出到 MongoDB(内置),ElasticSearch 或 InfluxDB 等。
3.5. Zuul
Zuul 是 Netflix 开源的基于 Java 的 API 网关组件。
图片
Zuul 包含多个组件:
- zuul-core:该库包含编译和执行过滤器的核心功能。
- zuul-simple-webapp:该 Webapp 展示了一个简单的示例,说明如何使用zuul-core构建应用程序。
- zuul-netflix:将其他 NetflixOSS 组件添加到 Zuul 的库-例如,使用Ribbon路由请求。
- zuul-netflix-webapp:将 zuul-core 和 zuul-netflix 打包到一个易于使用的程序包中的 webapp。
Zuul 提供了灵活性和弹性,部分是通过利用其他 Netflix OSS 组件进行的:
- Hystrix 用于流控。包装对始发地的呼叫,这使我们可以在发生问题时丢弃流量并确定流量的优先级。
- Ribbon 是来自 Zuul 的所有出站请求的客户,它提供有关网络性能和错误的详细信息,并处理软件负载平衡以实现均匀的负载分配。
- Turbine 实时汇总细粒度的指标,以便我们可以快速观察问题并做出反应。
- Archaius 处理配置并提供动态更改属性的能力。
Zuul 的核心是一系列过滤器,它们能够在路由 HTTP 请求和响应期间执行一系列操作。以下是 Zuul 过滤器的主要特征:
- 类型:通常定义路由流程中应用过滤器的阶段(尽管它可以是任何自定义字符串)
- 执行顺序:在类型中应用,定义跨多个过滤器的执行顺序
- 准则:执行过滤器所需的条件
- 动作:如果符合条件,则要执行的动作
3.6. Gravitee
Gravitee 是 http://Gravitee.io 开源的,基于 Java 的,简单易用,性能高,且具成本效益的开源 API 平台,可帮助组织保护,发布和分析您的 API。
Gravity 提供网关,API 门户和 API 管理,其中网关和管理 API 部分是开源的,门户需要注册许可证来使用。
4. 总结
- nginx
Nginx 基于 C 开发的高性能 API 网关,拥有众多的插件,如果你的 API 管理的需求比较简单,接受手工配置路由,Nginx 是个不错的选择。 - Kong
Kong 是基于 Nginx 的 API 网关,使用 OpenResty 和 Lua 扩展,后台使用 PostgreSQL,功能众多,社区的热度很高,但是性能上看比起 Nginx 有相当的损失。如果你对功能和扩展性有要求,可以考虑 Kong。 - APISIX
APISIX 和 Kong 的架构类似,但是采用了云原生的设计,使用 ETCD 作为后台,性能上比起 Kong 有相当的优势,适合对性能要求高的云原生部署的场景。特别提一下,APISIX 支持 MQTT 协议,对于构建 IOT 应用非常友好。 - Tyk
Tyk 使用 Golang 开发,后台使用 Redis,性能不错,如果你喜欢 Golang,可以考虑一下。要注意的是 Tyk 的开源协议是 MPL,是属于修改代码后不能闭源,对于商业化应用不是很友好。 - Zuul
Zuul 是 Netflix 开源的基于 Java 的 API 网关组件,他并不是一款开箱即用的 API 网关,需要和你的 Java 应用一起构建,所有的功能都是通过集成其它组件的方式来使用,适合对于 Java 比较熟悉,用 Java 构建的应用的场景,缺点是性能其他的开源产品要差一些,同样的性能条件下,对于资源的要求会更多。 - Gravitee
Gravitee 是 http://Gravitee.io 开源的基于 Java 的 API 管理平台,它能对 API 的生命周期进行管理,即使是开源版本,也有很好的 UI 支持。但是因为采用了 Java 构建,性能同样是短板,适合对于 API 管理有强烈需求的场景。