网关和BFF是如何演化出来的
初代架构-V1
V2
存在的问题:
- 内部服务强耦合问题:接口耦合、域名耦合
- 每个对外的服务需要新的域名、域名购买的开销问题
- 服务暴露在公网存在安全问题
-
V2.5引入无线BFF
无线BFF:为前端而开发的后端,可以认为是一种代理适配服务,他将后端的微服务进行适配,进行聚合裁剪。
该架构的优点: 解耦:无线APP和内部的微服务不强耦合,通过引入BFF使得两边都可以变化。如果后端发生变化,通过BFF屏蔽,前端不发生变化,如果前端发送变化,通过BFF屏蔽,后端不发生变化。
- 无线APP只需要知道无线BFF提供的域名和提供的接口,不需要知道内部的微服务和他的实现细节。
- 无线BFF只需要一个新域名
- 内部服务在BFF后面,不会暴露在公网上面,这样安全风险就降低了。
- 聚合和裁剪逻辑在BFF上就可以进行操作
随着业务量的增长和研发团队规模的扩大,也逐渐暴露出下面的一些问题:
- 首先只有一个BFF,随着业务团队的增加,单块的BFF堆积了大量的业务逻辑,变得越来越臃肿,升级和维护变得越来越困难。另外单块的BFF和多团队直接出现了不匹配的问题,团队直接沟通成本变高了,交付效率变低。
- 无线BFF不仅有各个业务之间的聚合、裁剪、适配,还有很多业务逻辑,还引入了很多跨界面的逻辑,比如安全认证,日志监控,熔断等等。随着时间的推移,代码变得越来越复杂,技术栈堆的越来越多,开发效率在下降,缺陷数量也在不断上升。
无线BFF是单例的,如果当中有严重的代码缺陷,如果突发流量洪峰,会造成无线集群宕机,导致无线应用不可用。
V3
所以V2.5是存在诸多问题的。针对当前存在的问题,架构师经过思考,一方面决定将单个无线BFF进行解耦拆分,针对不同的业务线,引入独立的BFF集群,另外一方面在外部设备和内部的BFF之间再引入一个新的角色——API网关。
新架构的调整:无线BFF按照团队或者业务线的边界进行解耦拆分,拆分成若干个BFF微服务,每个业务线团队可以并行开发和交付各自负责的这个微服务。
- 网关一般由独立的团队进行开发和运维,网关负责
- 路由:将来着无线设备的请求路由到后端具体的
- 认证:对涉及敏感数据调用的API进行集中的认证鉴权
- 监控:对API调用的性能和日志的监控
- 限流熔断:当初的流量洪峰,BFF微服务出现延迟或者故障的时候,网关能够主动的进行限流熔断,保护好微服务,同时确保前端服务不受影响。
在新的云架构层中,网关承担了重要的角色,他是解耦拆分和后续升级迁移的预期,在网关的配合下,各个业务线团队可以独立的开发和交付各自负责的微服务,研发效率大大提升了。
V4
在新的业务诉求下,要开放内部的业务能力,建设开放平台,借助第三方设计进行创新。另外在单页H5前端是一种新趋势,是一种更好的用户体验,支持前端团队快速的迭代。此时需要支持这种前后端分离架构,能够实现快速交付和创新。第三个则是原来的反向代理Nginx技术比较偏运维,严格来说不是一种可维持网关,而且Nginx和网关有重叠,所以考虑废弃Nginx,引入统一的可配置网关层,另一方面实现基于网关的分离架构,另一方面基于可编程网关实现更灵活的部署升级能力,提供金丝雀发布、规则发布和蓝绿发布这些能力。
去掉了老的Nginx集群,由网关统一负责承担反向路由、负载均衡。
网关和反向代理的关系
反向代理VS网关
Zuul
https://zuul-ci.org/docs/zuul/discussion/concepts.html
Envoy
Traefik
https://doc.traefik.io/traefik/
网关是否需要分集群部署
反向代理+网关部署架构
统一网关部署架构
优势:所有应用可以统一部署,不存在跨域问题,应用和微服务在同一个域下面,就不存在跨域问题。
不足:
- 统一容错处理:Web应用出错需要展示一个错误页面,API出错是一个错误消息
- 认证方式的差异:使用统一网关处理时鉴权的差异不好区分,就必须在网关上面有区分容器。
是否需要统一网关还是要看公司的业务和团队规模,如果开发团队规模比较小的话,刚开始就没必要拆分网关集群,到一定的规模才拆分网关集群。
设计一个最简网关
Faraday网关内核设计
生产级网关需要考虑的环节
生产扩展点
- 限流熔断
- 动态路由和负载均衡
- 基于Path的路由
- api.xxx.com/pathx
- 截获器链
- 日志采集和Metrics埋点
- 响应流优化
主流开源网关概览
|
| 支持公司 | 实现语言 | 亮点 | 不足 | | —- | —- | —- | —- | —- | | Nginx(2004) | Nginx Inc | C/Lua | 高性能,成熟稳定 | 门槛高,偏运维,可编程弱 | | Kong(2014) | Kong Inc | OpenResty/Lua | 高性能,可编程API | 门槛较高 | | Zuul1(2012) | Netflix/Pivotal | Java | 成熟,简单门槛低 | 性能一般,可编程一般 | | SpringCloud GateWay(2016) | Pivotal | Java | 异步,配置灵活 | 早期产品 | | Envoy(2016) | Lyft | C++ | 高性能,可编程API/ServiceMesh集成 | 门槛较高 | | Traefik(2015) | Containous | Golang | 云原生,可编程API/对接各种服务发现 | 生产案例不多 |