微服务设计模式之API 网关
简介
API 网关是目前非常成熟的一种微服务与外界通讯方式的一种选型,当前你的架构是从单体架构 Monolithic
迁移过来的时候,你会发现新的服务无法很好地从旧有系统中接管流量。
这个接管,或者说迁移的过程很复杂,也很危险,一般我们也会从小流量的非核心服务开始拆,拆分完之后,你就会发现问题了:流量怎么导到新服务上面去呢?
一种选择是在原服务上将数据转发至新服务,但是这也有问题:新服务其实相当于没有完全拆分出去,当任何一方出问题的时候,其它服务也会受影响。
另一种选择是会从软负载均衡上修改配置来达到拆分的目的,但是配置的管理是个大难题,一旦出了问题,影响的可能就是某个机房或者整站的服务稳定。另外,当拆分越来越多的时候,问题也随之而增加:复杂度太高,每次修改都是提心吊胆。
于是,API 网关就可以承担这个关键角色了,它将所有的微服务结合在一起,对外屏蔽细节(外部不需要知道是哪些微服务提供了数据),作为一个单点对外提供服务。不知道你想起了什么没有,对,就是设计模式中的经典:Facade 模式。
同时还有一种差异版本:BFF,也就是为每个客户端单独建立不同的 API 网关。
好了,既然 API 网关那么好,接下来该怎么做呢?当然是挑选合适的网关了。
选型需求
在挑选之前,我们需要明确自己的需求,我们需要的网关它至少需要有以下核心功能:
- 强悍的负载均衡能力;
- 支持动态服务管理服务,最好能跟服务发现结合在一起;
- 支持故障控制:健康检查、限流、熔断、重试;
- 详细的监控指标(比如支持 Prometheus);
- 日志聚合(其实这个应该说是基本功能);
附加功能:
- 支持分布式追踪,支持 Opentracing;
- 金丝雀发布,灰度发布,A/B 测试;
- 统一认证:JWT,OAuth,Basic auth 等;
- HTTP 缓存;
- 请求、返回内容的显示以及修改;
- 请求限制:机器人检测、黑白 IP 名单;
几个推荐选型
个人认为,网关作为微服务架构里面的基石应用,应该选用接近底层以及性能比较高的语言去实现,比如 C/C++,Golang 以及 Rust 等。
目前比较成熟以及用的比较广泛的网关有以下几种:
- GitHub - Kong/kong:基于 OpenResty 那一套做的,依赖于 Nginx 强悍的性能,添加了动态服务管理功能,以及插件机制,语言是 lua ,假如自己拓展需要学习新语言;
- GitHub - TykTechnologies/tyk:用 Golang 实现的网关,如果团队使用 Golang 技术栈,到时可以考虑下;
- GitHub - Netflix/zuul:用 Java 实现的网关,目前看来只适合 Java 技术栈;
这里抛开最后一个不谈,其中前两个是目前用得比较广泛的,这两者几乎就是市场的老大与老二了。
除了以上几个,另外还有几个网关值得留意:
- fagongzi/gateway:国人用 Golang 实现的的 gateway,可以看看,假如东西确实很不错,再加上之后能运营好,做成收费服务,前途可期;
- hellofresh/janus:也是让人眼前一亮的网关,比如支持 Opentracing 以及 HTTP/2;
Kong vs Tyk
关于两者的比较,有好事者在两个产品的社区里面发了相同的帖子(大家好好学习这位同学,非常机智):
- https://discuss.konghq.com/t/api-gateway-comparison-kong-vs-tyk/534
- https://community.tyk.io/t/comparison-between-tyk-and-kong/2364
Kong 的社区回复:
- Kong 的功能丰富、插件齐全;
- 进可当做 Ingress 接管入口中央集权制,退可当 Mesh 去中心化分封制;
- Nginx + lua 性能杠杠的,扛起了全球 10% 的流量,连 CloudFlare 跟我们用的都是一样的技术栈,而且 lua 也很容易学习;
- 市场上独领风骚;
- 基准测试中是最快的;
- 心动了没,赶紧找我们销售;
Tyk 的社区回复:
- 客户支持快;
- Kong 的插件只能用 lua 写,Tyk 则不然,lua、Python、JS 统统支持,另外 插件里面的 gRPC 也是支持的;
- Kong 依赖于 Nginx,假如 Nginx 出了 bug,他们很难修复,Tyk 则不然,全部技术栈都是他们可控的;
- 两者的性能差不多,2k qps 完全不是问题,能满足大部分需求;
- Kong 的 UI 是企业版才有的,Tyk 免费用;
- 我们不靠 VC 支持,玩的是长线战略;
然后再看看一个『第三方』的测评:
这里插一句:之所以打引号,是因为觉得他们的图表是偏向于 Kong 的,在那个最明显的对比图中,如果不仔细看,会以为 Kong 的性能是 Tyk 的两倍。
https://www.bbva.com/en/api-gateways-kong-vs-tyk/
从结果来看,Kong 的性能更胜一筹:超出约 **25%**,而 Tyk 在去掉一些插件之后的性能也能增加 20% 左右。
因此,性能上的考量不是非常重要了,而且你也完全可以通过增加更多的节点来获取更高的整体性能。
而在 stackoverflow 的一个帖子中,发现大家还是力挺 Tyk 的:
https://stackoverflow.com/questions/46769814/is-there-a-comprehensive-comparison-between-tyk-vs-kong
很显然,因为 Kong 的先发优势(2011 年成立 [3])以及站在了 Nginx 这个巨人的肩膀上,发展非常迅速,目前使用人数以及社区都远远高于 Tyk。Tyk(2015 年成立 [3]) 作为老二,在没有资本压力的情况下,在努力运营社区、维护社区的关系,这点还是不错的。而 Kong 的话,商业气息更重一些,具体就表现在了非常关键的管理界面上:如果你不付钱,那你只能用开源社区的版本。
其它
收费
不知道你注意到了什么,我这个过程中其实很看重的一点就是商业支持:我不相信一个长久无法获利的工具能够非常优秀,因为这不利于这个项目的长期发展,好东西还是得花钱的。
测试
你需要一个 Echo server,简单来说,就是把请求包含的内容给你返回回来,同时还包含所在实例、进程的信息等等。然后,通过在 CI 中直接拉起这一堆镜像,用脚本测试,对比返回结果即可。
最后,在 CD 中将测试过的配置发布至准生产环境、生产环境即可。
Echo Server 可以拿 Node.js 举例:
1 | import path from 'path' |
这段代码中,我加入了 delay
参数,方便对网关进行性能测试。
监控
之前可以用 GitHub - yciabaud/kong-plugin-prometheus: Prometheus metrics exporter for Kong API management,但最近的 0.14.0 版本,官方集成了自己的 Promethus 监控,因此上面的这个监控插件得拜拜了。
Tyk 的监控是包含在工具套件里面的,如果要使用它们的东西,你得注册获取免费的 license,并且免费版本只能使用一个 gateway 节点,由于怕它们的销售骚扰,赖得注册去测试了。
Kong 的 UI
目前除了官方企业版才提供的管理界面,目前有以下两个选择
- GitHub - PGBI/kong-dashboard: Dashboard for managing Kong gateway
- GitHub - pantsel/konga: More than just another GUI to Kong Admin API
Ref
- API gateway pattern
- Building Microservices: Using an API Gateway
- API Gateways: Kong vs. Tyk | 4-Traders
首发于 Github issues: https://github.com/xizhibei/blog/issues/82 ,欢迎 Star 以及 Watch
本文采用 署名-非商业性使用-相同方式共享(BY-NC-SA)进行许可作者:习之北 (@xizhibei)
原链接:https://blog.xizhibei.me/zh-cn/2018/07/15/microsevices-design-pattern-api-gateway/