原文作者:易久平
原文链接:分享实录 | 将 NGINX 打造成功能强大的 API 网关(下)
NGINX 唯一中文官方社区 ,尽在http://nginx.org.cn
编者按——本文为 NGINX Sprint China 2022 年度线上大会的分享实录,点击这里免费观看大会完整视频回放。由于文章较长,将分为上下两篇发布。点击《分享实录 | 将NGINX打造成功能强大的API网关(上)》阅读上篇。
本次分享中,我们将讨论本次分享将全面介绍 API 网关的概念和功能,以及如何利用 NGINX 打造一个功能强大的 API 网关。
如何打造一个 API 网关呢?从工程角度,我们还是需要符合一些软件开发的规律,或是软件工程的一些思想去完成整个开发过程。总体来讲,可以分为 7 大步骤完成开发:
首先,这个 API 网关的功能其实只是一个子集。作为一个 API 网关,除了 API 的反向代理功能外,还需要通过与 Eureka、Nacos 等注册中心集成发现后端服务实例。另外还需要明确 API 所支持的协议,比如说 HTTP 协议、gRPC 协议,或者是 Web Socket 协议,同时 API 需要具有分权分域的管理能力,以及地址匹配或者自动化配置的能力,所以需要思考如何更好的管理 API。
第二点需要关注 API 的安全,比如 API 的访问控制,API 的认证方式等等。
第三点是 API 流量控制,需要保证 API 网关作为流量入口能保护后端应用,它可以做到流量限速、请求改写、响应改写,或者进行统一的错误码转换,甚至进行一些应用优化。另外还需要实现流量调度,除了反向代理负载均衡常见的能力以外,还可以实现灰度发布、蓝绿发布能力或者流量计算能力。
上图是一个简单的技术架构设计,当然这个技术架构是仅是一个蓝图,本次实验并没有把所有的功能实现,主要实现的是数据面和控制面的能力。
控制面的核心作用是与配置中心或者是管理面集成获取配置数据,并且转译成 NGINX 配置。这个过程有可能是生成配置文件后做 Reload,也有可能是直接调用 NGINX 的 API 动态加载配置。
另外网关控制服务的功能主要是写入或修改配置。本次演示里用 etcd 保存配置,将 etcd 当成数据库使用,先把配置写到 etcd,再通过 Confd 执行模板将配置转换成 NGINX 配置。
API 网关作为数据面,除了作为业务服务的反向代理外,它可能还会对接两种类型的服务:第一种是对接认证鉴权中心进行 API 的访问认证或者鉴权,另一种是对接监控中心实现数据面的监控
NGINX 有许多的功能,为了实现特定的功能,需要去把这些能力进行规划。我们可以把它规划成目录结构,这些目录结构需要按照不同的维度进行考虑。
比如配置是否经常修改,是否根据业务维度进行拆分、底层配置是否要与接收请求的 HTTP 服务配置分开、后端服务配置是否分开等等。所以我们需要进行这样的规划,API 网关的管理才更简单,更解耦。
模型决定了整个应用系统的架构,在本次分享的 API 网关架构里,我们设计了一个 API Gateway 模型,上图将模型分为两种颜色表示,深蓝色部分我们定义为实体,它们具有唯一的 ID 及独立的生命周期,浅蓝色的部分定义为值对象。我们用领域驱动的思想来定义模型,所以最上层会有一个网关 (Gateway) 的实体。
Gateway 代表的是网关集群,集群内存在多个 NGINX 实例,同一个 Gateway 可能会有不同的 Server。Upstream 比较好理解,作为上游服务一定会有一个模型描述上游服务集群。Member 可能有很多种形式去创建它,它可能是手动配置,也可以是自动发现,也可以是 Excel 去导入。
对于上游服务集群 (Upstream) 来说,我们也会有一些策略,一般会有三类策略。首先,是否要做一些流量的负载均衡;其次,针对于某些状态的会话是否要做到会话保持,从而保证服务的连续性;最后,是否要做一些健康检查功能去探测后端服务的可用性,明确是否要进行熔断降级。
当模型设计完毕后,需要进行代理开发,本次分享案例,使用的代理为 Confd,因为 Confd 本身是一个配置变更工具,它支持比较灵活的模板功能,它也支持对接 etcd、Redis 等 NoSQL 配置中心或缓存服务器。这样我们可以用它来监听配置变化,并完成配置生成和加载。
模板的概念大家都已近了解很多了,模板其实是采用了动静结合的思想,把一部分静态的东西放到模板里面,把一部分动态的东西转换成变量。如果模板灵活一些的话,可以做一些 if else 的判断,也可以做 for 循环,甚至实现了一些扩展能力,调用一些指令等等。
功能测试分为场景和用例两种维度,比如在测试 TLS 的卸载场景时,需要考虑证书是否过期以及证书存放位置,场景和用例的设计一定要结合整体的功能规划来实现。
另外,在整个测试过程中一定有一个后端服务。用例里实现了一个简单的应用,这个应用功能非常简单,只是用来做 API 的测试,简单实现了几个业务领域的服务,主要是为了满足这次测试需求,所以并没有实现的太复杂。
或许还会用到自动化测试工具,因为在后续的更新中可能会新增功能,在新增功能的过程中一定要保证原有功能的可用性,所以最好能自动化的去做集成和交付。
NGINX 唯一中文官方社区 ,尽在 nginx.org.cn
更多 NGINX 相关的技术干货、互动问答、系列课程、活动资源:
开源社区官网:开源Web服务提供商 - NGINX开源社区
微信公众号:NGINX郑重宣布对开源社区的全新承诺