下图是我从网络上找到的一个微服务架构的简单架构图,如图可见 API Gateway 在其中起到一个承上启下的作用,是关键组件。
图片来源于网络
在更通用的场景下我们会使用 NGINX 这样的软件做前置,用来处理SLB负载均衡过来的流量,作用是反向代理、集群负载均衡、转发、日志收集等功能。
然后再将 NGINX 的请求 proxy 到 API Gateway 做统一网关处理。
在上面的这个场景下 API Gateway 可以包含以下功能:
安全
限流
缓存
熔断
重试
负载
反向路由
认证、鉴权
日志收集和监控
其他
熟悉 NGINX 的朋友应该可以看出来,上面列出的这些功能和 NGINX 的部分功能是重合的,不过由于架构结构不同,在上面我提到的场景中,即 NGINX 在前 API gateway 在后的结构中,他们两者关注的维度也不一样,所以即使有重合也正常。
下图是我基于云原生微服务架构设计的架构图其中前端流量是通过 SLB -> NGINX -> API Gateway 再到具体服务。
由于后端采用java 的 spring cloud 开发的,所以在语言一致性上更倾向 java 语言开发的组件。如上图虽然在 API Gateway 的位置上写的是 spring cloud gateway,然而也可以采用像 zuul、zuul2 这些同样是 java 语言开发的组件。对于具体 zuul 和 spring gateway的选型,是这样考虑的:
|
spring cloud gateway | zuul |
---|---|
性能 | 性能比 Netflix Zuul 好将近一倍 |
社区和文档 | spring社区非常活跃 |
可维护性 | 基于spring官方维护性强 |
亮点 | 异步、配置灵活 |
不足 | 早期产品、新版本踩坑 |
Spring Cloud Gateway 的性能比 Zuul 好基本上已经是业界公认的了,实际上,Spring Cloud Gateway 官方也发布过一个性能测试,这里节选如下数据:
Spring Cloud Gateway 构建于 Spring 5+,基于 Spring Boot 2.x 响应式的、非阻塞式的 API。同时,它支持 websockets,和 Spring 框架紧密集成。从目前来看,gateway替代zuul是趋势。基于以上这些,综合考虑在架构中使用Spring Cloud Gateway。
现代 API Gateway 越来越需要或者流行可编程网关了。上面介绍的都是基于 java 语言开发的可编程的 API Gateway。下面我们来聊聊非 java 语言开发的网关。从前面的架构图上看,我们完全可以将 NGINX 和 API Gateway 合并起来,他们的功能的重合点自然消除了,也能降低架构的复杂性和运维成本。
NGINX 是一款优秀的软件,然而它在动态性方面的不足导致不太灵活,后面出现的 OpenResty、tengine 这些基于NGINX 和 Lua 的软件在动态性、灵活方面有本质上的改善,加上基于Lua脚本和插件,可以实现所谓的可编程。
市面上基于OpenResty 以 API Gateway 为应用场景的应用软件有 Kong、APISIX、tyk 等。以下是CNCFland scape 的一个概览
经过考虑,在架构上,后期有可能将 NGINX、Spring Cloud Gateway 替换成KONG 或其他软件。
比较了一下,目前最火的应用是Kong,另一个国产的 APISIX 趋势也是很猛,且他们的技术栈雷同,所以我在选型上找到了APISIX的作者做的对比:
通过性能测试可以看到,在不开启插件的情况下,Apache APISIX 的性能(QPS 和延迟)是 Kong 的2倍,但开启了两个常用插件后,性能就是 Kong 的十倍了。
无论从性能、可用性、可编程代码量等各个维度APISIX都是非常优秀的,目前唯一担心的就是这种早期项目没有太多大规模应用实践,如果上生产还是有风险,可在测试环境调研,并等待有更多生产实践作为依据。 当然如果架构师认为风险并不大,且经过了测试调研也是可以上的。
前面我们将 API Gateway 的网关选型介绍了一下,请求通过网关后一般不会直接打到具体微服务上的,而是会通过BFF层,所谓的BFF,即 backend for frontend 面向前端的后端。具体来说它的职能包括:
api数据裁剪
接口编排
接口调用
这层有的公司会按业务进行多个BFF的建设,在BFF中又有可能拆成多个服务,比如支撑首页的,支持列表页的,或者只有一个服务,支撑某个应用的所有请求的。
有了BFF层,前后端就会更好的解耦,前端不用再调用多个接口,然后再组织数据,微服务后端也只需要关心自己服务边界内的事情。
然而在实践的过程中会出现一些问题:
大量业务逻辑从前后端集中在了BFF层
BFF层逻辑复杂,代码量越来越大,难以维护
BFF API版本维护复杂
前端端接口职责不清,扯皮的结果就是放在BFF层
以上是我真实遇到过的场景。所以在后面的架构设计和实施中,这些情况会尽量避免,但没有从技术上解决根本问题。直到 GraphQL 的出现,让我眼前一亮,给了我一个很好的解决方案。关于GraphQL的搭建,数据交换等细节这里就不展开说了,感兴趣的可以从网上找到很多资料。
下图是我从网络上找的一个符合我心目中的理想架构。
图片来源于网络
说起来简单,做起来没那么容易 ,细节是魔鬼,每利用一个新的技术都会经历一波打怪升级的过程。不过总体来说利用GraphQL确实能从理论上解决上面所说的问题。而重点是如何将它结合进你的系统架构中,并且发挥出它的优势。架构很多时候是在做权衡和选择
关注公众号 获取更多精彩内容