一, 何为 API 网关?
APIGateway 即 API 网关, 所有请求首先会经过这个网关, 然后到达后端服务, 有点类似于 Facade 模式. API 网关作为系统接口对外的统一出口, 可以减少调用方对服务实现的感知.
没有 API 网关时的系统结构如下图 1: 由图可以看出, 在没有 API 网关作为统一出口的情况下, 需要调用方自己组合各种服务, 而且容易让调用方感知后端各种服务的存在.
图 1 没有网关时的系统结构
加入 API 网关时的系统结构如下图 2: 由图可以看出, 在加入了 API 网关之后, 通过网关暴露接口给调用方, 调用方可以在不感知后端服务的情况下调用服务, 而且通过统一的接口, 后端服务接口的变化不会影响调用方, 后端服务变化可以通过网关的转换, 对外仍然保持一致的风格.
图 2 加入网关的系统结构
二, 网关的几种使用场景
图 3 使用场景
2.1, 面向 web App
这类场景, 在物理形态上类似前后端分离, 此时的 Web App 已经不是全功能的 Web App, 而是根据场景定制, 场景化的 App.
2.2, 面向 Mobile App
这类场景, 移动 App 是后端 Service 的使用者, 此时的 APIGateway 还需要承担一部分 MDM(此处是指移动设备管理, 不是主数据管理) 的职能.
2.3, 面向 Partner OpenAPI
这类场景, 主要为了满足业务形态对外开放, 与企业外部合作伙伴建立生态圈, 此时的 APIGateway 需要增加配额, 流控, 令牌等一系列安全管控功能.
2.4, 面向 Partner ExternalAPI
这类场景, 业界提的比较少, 很多时候系统的建设, 都是为了满足企业自身业务的需要, 实现对企业自有业务的映射. 当互联网形态逐渐影响传统企业时, 很多系统都会为了导入流量或者内容, 依赖外部合作伙伴的能力, 一些典型的例子就是使用合作方账号登录,使用第三方支付平台支付等等, 这些对于企业内部来说, 都是一些外部能力. 此时的 API GW 就需要在边界上, 为企业内部 Service 统一调用外部的 API 做统一的认证,(多租户形式的) 授权, 以及访问控制.
三, APIGateway 的作用
通过上面的几种使用场景, 我们归纳 APIGateway 的主要作用包括如下几点:
3.1, 统一对外接口
当用户需要集成不同产品或者服务之间的功能, 调用不同服务提供的能力. 利用 APIGateway 可以让用户在不感知服务边缘的情况下, 利用统一的接口组装服务.
对于公司内部不同的服务, 提供的接口可能在风格上存在一定的差异, 通过 APIGateway 可以统一这种差异. 当内部服务修改时, 可以通过 APIGateway 进行适配, 不需要调用方进行调整.
3.2, 增加系统安全性
APIGateway 对外部和内部进行了隔离, 减少对外暴露服务可以增加系统安全性, 保障了后台服务的安全性.
3.3, 统一鉴权
通过 APIGateway 对访问进行统一鉴权, 不需要每个应用单独对调用方进行鉴权, 应用可以专注业务.
3.4, 服务注册与授权
可以控制调用方可以使用和不可以使用的服务.
3.5, 服务限流
通过 APIGateway 可以对调用方调用每个接口的每日调用及总调用次数限制.
3.6, 提升预发能力
为服务熔断, 灰度发布, 线上测试提供简单方案.
3.7, 全链路跟踪
通过 APIGateway 提供的唯一请求 Id, 监控调用流程, 以及调用的响应时间.
四, APIGateway 需要考虑的因素
4.1, 安全性问题
企业在把服务暴露给外部使用时, 首先要确保服务使用的安全, 防止外部的恶意访问对公司业务的影响, 特别是涉及交易方面的服务, 更是要全面考虑安全性. 为确保安全, 需要考虑在通讯链路的建立, 通讯数据的加密, 数据的完整性等方面.
4.2, 性能问题
作为企业 API 的入口, 所有的请求都会经过 APIGateway 进行转发, 可想而知, 对 API 网关的访问压力是巨大的, 有的网站甚至达到每分钟上千万的访问量. 特别是在一些互联网企业, 海量的移动终端每时每刻都需要与后端的服务进行交互, 如果不能保证 APIGateway 的高性能, 企业在网关层需要投入大量的设备和成本.
4.3, 高可用问题
APIGateway 作为逻辑上的单点, 一旦发生问题, 将造成企业服务的不可用, 对企业来说可能造成的致命的影响. 计算短时间的不可用, 也会给企业带来直接的经济损失. 所以, 如何保证 APIGateway 的 7*24 小时的稳定运行, 网关的自动伸缩, API 的热更新等问题, 都是企业级的网关需要考虑的.
4.4, 扩展性问题
企业 APIGateway 提供了一个脚手架, 一些非功能性的问题, 例如日志, 安全, 负载均衡策略, 鉴权等. 这些插件会随着企业业务规模等的变化进行不断的强化与调整. 这就需要网关层提供这样一种机制, 使得可以灵活地进行这些调整和变化, 而不用频繁对网关层进行改动, 确保网关层的稳定性.
4.5,API 高效运维的问题
API 在上线, 发布过程中, 都需要涉及到网关层的配合, 例如, 需要网关层知道 API 发布的地址, API 的接口形式, 报文格式, 也需要网关层对后台 API 进行封装. 在 API 调整后, 需要作出相应的修改. 所以, API 网关设计时, 需要明确网关层与服务层的职责切分与协作模式, 使得 API 的管理, 发布更加高效.
4.6,API 全生命周期的管理
API 服务的全生命周期, 包括服务的开发, 测试, 上线发布; 服务使用的申请, 开通; 服务分类分级别的管理, 服务使用情况的监控, 计费等等.
一个企业可能会暴露成百上千个 API, 日常也会经常进行 API 的发布, 升级, 改造, 下架等操作. 对不同的服务, 不同的访问者, 需要提供不同的服务访问策略. 有的商业 API 公司, 还需要对 API 的使用进行付费. 所以, 与 API 网关配套的, 需要一套完善的自助系统, 提供给服务的提供者, 管理者, 使用者, 来对服务的发布, 使用, 和运营.
五, APIGateway 的常用实现方案
5.1, 开源 API 网关框架 Spring Cloud Zuul
Spring Cloud Zuul
Zuul 是 Netflix 出品的一个基于 JVM 路由和服务端的负载均衡器. 它的主要功能有: 认证, 压力测试, 金丝雀测试, 动态路由, 负载削减, 安全, 静态响应处理和主动 / 主动交换管理. spring zuul 是 spring Cloud 的组件, 可以和 spring cloud 的各个组件结合使用.
SpringCloud 的整体组建包括: Zuul,Ribbon,EureKa,Fein,Hystrix 等. 其中 Zuul 就是一个类似 APIGateway 的组建, Ribbon 是类似于 Nginx 的代理服务器, Eureka 用于注册和发现服务, Hystrix 可以作为整个架构的断路服务, 用于服务降级. Fein 可以作为一个 Rest 服务的提供者, 可以供内部服务之间相互调用.
5.2, 开源 API 网关框架 Kong
Kong
Kong 是一个现成的 APIGateway 的解决方案, Kong 本身是基于 Nginx 开发的, 在性能和稳定性上都没有问题.
5.3,Nginx+Lua
Nginx + Lua
基本功能:
1) 静态 web 资源服务器, 能够缓存打开的文件描述符
2) 支持 http/imap/pop3/smtp 的反向代理; 支持缓存, 负载均衡
3) 支持 fastcgi(fpm)
4) 模块化, 非 DSO 机制, 支持过滤器 zip 压缩, SSI 以及图像大小调整
5) 支持 SSL
Nginx 的扩展功能:
1) 基于名称和 IP 的虚拟主机
2) 支持 keepalive 的保持机制
3) 支持平滑升级
4) 定制访问日志, 支持使用日志缓存区提高日志存储性能
5) 支持 url rewrite
6) 支持路径别名 (root 或 alias 指定)
7) 支持基于 IP 以及用户的访问控制
8) 支持传输速率限制, 并发限制
性能和高可用性上:
Nginx 性能极高, Nginx 先天的事件驱动型设计, 全异步的网络 I/O 处理机制, 极少的进程间切换以及许多优化设计, 都使得 Nginx 天生善于处理高并发压力下的互联网请求. Nginx 的稳定性也在各大网站得到验证. 官方提供的常用模块都非常稳定, 每个 worker 进程相对独立, master 进程在 1 个 worker 进程出错时可以快速 "拉起" 新的 worker 子进程提供服务. 支持热部署, 可以不停机更新配置文件, 更新日志文件, 更新服务器程序版本.
扩展性上:
Nginx 的设计极具扩展性, 它完全是由多个不同功能, 不同层次, 不同类型且耦合度极低的模块组成. 因此, 当对某一个模块修复 Bug 或进行升级时, 可以专注于模块自身, 无须在意其他
易用性上:
Nginx 使用最自由的 BSD 许可协议, 允许用户在自己的项目中直接使用或修改 Nginx 源码, 有大量的插件可以利用. 但是, Nginx 模块需要用 C 开发, 而且必须符合一系列复杂的规则. 虽然通过第三方模块, 可以支持 Nginx 与 Perl,Lua 等脚本语言集成工作, 但对使用者的要求还是很高.
如果只是使用 Nginx 做 APIGateway 还是不够的, 因为 Nginx 有单点问题, 这里可以结合阿里云的 SLB 一起做.
从对上面三种方案的比较中可以看到, Spring Cloud Zuul 非常适合创业初期的团队, 快速搭建一个 "基本可用" 的 API 网关. Nginx 适合有较强研发团队, 自主开发企业自己的 API 网关, 当然如果结合阿里云的 SLB 去做的话还是挺方便的. Kong 适合于没有自身研发团队, 但需要拥有企业级 API 网关能力的公司.
六, 参考资料
- https://blog.csdn.net/akin_zhou/article/details/50373414
- https://blog.csdn.net/zhengpeitao/article/details/72722301
- https://blog.csdn.net/Tredemere/article/details/78246413?locationNum=10&fps=1
- https://help.aliyun.com/document_detail/27539.html?spm=a2c4g.11186623.6.539.WlAqyy
来源: http://www.jianshu.com/p/050833ad32eb