Java SpringCloud 网关

网关和BFF是如何演化出来的

初代架构-V1

可编程网关设计和实践 - 图1

V2

可编程网关设计和实践 - 图2
存在的问题:

  1. 内部服务强耦合问题:接口耦合、域名耦合
  2. 每个对外的服务需要新的域名、域名购买的开销问题
  3. 服务暴露在公网存在安全问题
  4. APP端需要大量的适配逻辑

    V2.5引入无线BFF

    可编程网关设计和实践 - 图3
    无线BFF:为前端而开发的后端,可以认为是一种代理适配服务,他将后端的微服务进行适配,进行聚合裁剪。
    该架构的优点:

  5. 解耦:无线APP和内部的微服务不强耦合,通过引入BFF使得两边都可以变化。如果后端发生变化,通过BFF屏蔽,前端不发生变化,如果前端发送变化,通过BFF屏蔽,后端不发生变化。

  6. 无线APP只需要知道无线BFF提供的域名和提供的接口,不需要知道内部的微服务和他的实现细节。
  7. 无线BFF只需要一个新域名
  8. 内部服务在BFF后面,不会暴露在公网上面,这样安全风险就降低了。
  9. 聚合和裁剪逻辑在BFF上就可以进行操作

随着业务量的增长和研发团队规模的扩大,也逐渐暴露出下面的一些问题:

  1. 首先只有一个BFF,随着业务团队的增加,单块的BFF堆积了大量的业务逻辑,变得越来越臃肿,升级和维护变得越来越困难。另外单块的BFF和多团队直接出现了不匹配的问题,团队直接沟通成本变高了,交付效率变低。
  2. 无线BFF不仅有各个业务之间的聚合、裁剪、适配,还有很多业务逻辑,还引入了很多跨界面的逻辑,比如安全认证,日志监控,熔断等等。随着时间的推移,代码变得越来越复杂,技术栈堆的越来越多,开发效率在下降,缺陷数量也在不断上升。
  3. 无线BFF是单例的,如果当中有严重的代码缺陷,如果突发流量洪峰,会造成无线集群宕机,导致无线应用不可用。

    V3

    所以V2.5是存在诸多问题的。针对当前存在的问题,架构师经过思考,一方面决定将单个无线BFF进行解耦拆分,针对不同的业务线,引入独立的BFF集群,另外一方面在外部设备和内部的BFF之间再引入一个新的角色——API网关。
    可编程网关设计和实践 - 图4
    新架构的调整:

  4. 无线BFF按照团队或者业务线的边界进行解耦拆分,拆分成若干个BFF微服务,每个业务线团队可以并行开发和交付各自负责的这个微服务。

  5. 网关一般由独立的团队进行开发和运维,网关负责
    1. 路由:将来着无线设备的请求路由到后端具体的
    2. 认证:对涉及敏感数据调用的API进行集中的认证鉴权
    3. 监控:对API调用的性能和日志的监控
    4. 限流熔断:当初的流量洪峰,BFF微服务出现延迟或者故障的时候,网关能够主动的进行限流熔断,保护好微服务,同时确保前端服务不受影响。

在新的云架构层中,网关承担了重要的角色,他是解耦拆分和后续升级迁移的预期,在网关的配合下,各个业务线团队可以独立的开发和交付各自负责的微服务,研发效率大大提升了。

V4

在新的业务诉求下,要开放内部的业务能力,建设开放平台,借助第三方设计进行创新。另外在单页H5前端是一种新趋势,是一种更好的用户体验,支持前端团队快速的迭代。此时需要支持这种前后端分离架构,能够实现快速交付和创新。第三个则是原来的反向代理Nginx技术比较偏运维,严格来说不是一种可维持网关,而且Nginx和网关有重叠,所以考虑废弃Nginx,引入统一的可配置网关层,另一方面实现基于网关的分离架构,另一方面基于可编程网关实现更灵活的部署升级能力,提供金丝雀发布、规则发布和蓝绿发布这些能力。
可编程网关设计和实践 - 图5
去掉了老的Nginx集群,由网关统一负责承担反向路由、负载均衡。

网关和反向代理的关系

反向代理VS网关

可编程网关设计和实践 - 图6

Zuul

https://zuul-ci.org/docs/zuul/discussion/concepts.html

Envoy

https://www.envoyproxy.io/
image.png

Traefik

https://doc.traefik.io/traefik/
image.png

网关是否需要分集群部署

反向代理+网关部署架构

可编程网关设计和实践 - 图9

统一网关部署架构

可编程网关设计和实践 - 图10
优势:所有应用可以统一部署,不存在跨域问题,应用和微服务在同一个域下面,就不存在跨域问题。
不足:

  • 统一容错处理:Web应用出错需要展示一个错误页面,API出错是一个错误消息
  • 认证方式的差异:使用统一网关处理时鉴权的差异不好区分,就必须在网关上面有区分容器。

是否需要统一网关还是要看公司的业务和团队规模,如果开发团队规模比较小的话,刚开始就没必要拆分网关集群,到一定的规模才拆分网关集群。

设计一个最简网关

Faraday网关内核设计

可编程网关设计和实践 - 图11

生产级网关需要考虑的环节

生产扩展点

  • 限流熔断
  • 动态路由和负载均衡
  • 基于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/对接各种服务发现 | 生产案例不多 |