对于微服务,常见的架构模型就是API网关+服务。

  • API网关实现鉴权、负载均衡、中间件等公共入口逻辑。
  • 服务实现具体的业务功能。

那么,API网关设计中又有什么坑呢?

1.0版本

直接将服务穿透到外网。

API层只是套了壳,加了鉴权、中间件而已。具体返回值由服务定。

  • 客户端到微服务直接通信,强耦合。根本不敢重构,一改结构客户端就崩了。
  • 需要多次请求,客户端聚合数据,工作量巨大,延迟高。
    • 缺乏统一的文档。
    • 如果一个页面由多个服务组成,比如商品、优惠券、相关推荐、评价。客户端要请求多个接口,命名规则还不一样。
    • 有的接口成功,有的接口失败,需要客户端自己做降级。
  • 协议不利于统一,各个部门间有差异,需要客户端端来兼容。
  • 面向“端”的API适配,耦合到了内部服务。
    • 每个服务都要为不同的设备做适配代码。
  • 多终端兼容逻辑复杂,每个服务都需要处理。
  • 统一逻辑无法收敛,比如安全认证、限流。

这样就导致了客户端、服务端都累得要死,谁都不讨好。

而我们的架构设计应该前轻后重的,面向业务场景设计接口,而不是面向数据资源。(不要让客户端做组装)

2.0版本

架构就是一层加一层。

添加了一个BFF层,backend for forntend,专门做适配。

我们新增了一个 app-interface 用于统一的协议出口,在服务内进行大量的 dataset join,按照业务场景来设计粗粒度的 API,给后续服务的演进带来的很多优势:

  • 轻量交互:协议精简、聚合。
  • 差异服务:数据裁剪以及聚合、针对终端定制化API。
  • 动态升级:原有系统兼容升级,更新服务而非协议。
  • 沟通效率提升,协作模式演进为移动业务+网关小组。

对接:

大前端---网关,只用对接数据结构。面向业务场景提供接口。

网关---服务,只需要对接服务接口。

BFF可以认为是一种适配服务,将后端的微服务进行适配(主要包括聚合裁剪和格式适配等逻辑),向无线端设备暴露友好和统一的 API,方便无线设备接入访问后端服务。

针对页面提供接口,比如商品页面,就一个接口,然后BFF层去调用多个服务,在这里做降级,比如优惠券服务没有返回就不显示就完了。

客户端只用和BFF层沟通,什么适配、协议、兼容、定制都是这一层来做。客户端感觉很爽。

服务端也只用提供基础数据,不用关心业务逻辑,不用管适配,返回的接口是什么结构。服务端也很爽。

BFF层只做了数据裁剪,兼容之类的逻辑,轻不轻松?也很轻松。

问题:

  • BFF单点了,single point of failure(单点故障)。也就是所有的流量都会到这一层, 如果有流量洪峰或者代码有bug,全盘宕机。

3.0版本

将BFF根据业务拆分,比如查看商品一个,订单页面一个。这样一个挂不会影响全局。

问题

  • 单个模块也会导致后续业务集成复杂度高,根据康威法则,单块的无线BFF和多团队之间就出现不匹配问题,团队之间沟通协调成本高,交付效率低下。
  • 很多跨横切面逻辑,比如安全认证,日志监控,限流熔断等。随着时间的推移,代码变得越来越复杂,技术债越堆越多。

有没有发现:

分久必合、合久必分。

分开了就有不能统一的地方,合并了就会单点故障。

4.0版本

跨横切面(Cross-Cutting Concerns)的功能,需要协调更新框架升级发版(路由、认证、限流、安全),因此全部上沉,引入了 API Gateway,把业务集成度高的 BFF 层和通用功能服务层 API Gateway 进行了分层处理。

在新的架构中,网关承担了重要的角色,它是解耦拆分和后续升级迁移的利器。

在网关的配合下,单块 BFF 实现了解耦拆分,各业务线团队可以独立开发和交付各自的微服务,研发效率大大提升。

BFF的划分:

  • 重要性
  • 垂直业务,闭环
  • 流量大小

另外,把跨横切面逻辑从 BFF 剥离到网关上去以后,BFF 的开发人员可以更加专注业务逻辑交付,实现了架构上的关注分离(Separation of Concerns)。

我们业务流量实际为:

移动端 -> API Gateway -> BFF -> Mircoservice

在 FE Web业务中,BFF 可以是 nodejs 来做服务端渲染(SSR,Server-Side Rendering),注意这里忽略了上游的 CDN、4/7层负载均衡(ELB)。

将通用逻辑做到了API网关层,BFF层专注于业务逻辑。

API层采用Nginx这种高可用的软件,基本不会挂,挂了重启即可,限流、负载等逻辑用模块实现,方便部署。

这一层完全和业务无关。

总结

当耦合性太高的时候,就加一层,作为缓冲。

当合并有单点的时候,就分开。当分开有不能统一的时候,就合并。

尽量让专门的人做专门的事情。减少业务对技术的耦合。

最新文章

  1. 打造Linux三流娱乐环境,二流办公环境,一流Java开发环境
  2. ccc2016
  3. Android 读写SD卡的文件
  4. HDOJ-三部曲一(搜索、数学)-1008-Prime Path
  5. Nginx初始化过程总结
  6. 基于smarty+medoo手搭php简单的框架
  7. Java的三种代理模式
  8. Itext中 根据html生成Word文件,包含图片
  9. Ubuntu16.04下的NetCore环境搭建
  10. DS博客作业03——栈和队列
  11. Javascript - Jquery - 其它
  12. ASP.NET之使用Ajax实现页面异步刷新(无需刷新整个页面)
  13. Java8函数式接口/Lambda表达式/接口默认方法/接口静态方法/接口冲突方法重写/lambda表达式指定泛型类型等
  14. 使用WPF教你一步一步实现连连看(三)
  15. mfc 虚函数
  16. html 画圆
  17. Accepted Technical Research Papers and Journal First Papers 【ICSE2016】
  18. 如何修改antd中表格的表头样式和奇偶行颜色交替
  19. Poj 题目分类
  20. vue-router实现SPA购物APP基本功能

热门文章

  1. dedecms织梦调用指定文章id
  2. 【PHP】数组按照字母排序
  3. Java基础系列(8)- 数据类型
  4. Linux系列(5) - 目录处理命令(2)
  5. Python创建Excel表格,Word并写入数据
  6. [转载]CentOS 7 创建本地YUM源
  7. 鸿蒙内核源码分析(中断概念篇) | 海公公的日常工作 | 百篇博客分析OpenHarmony源码 | v43.02
  8. AT4120-[ARC096D]Sweet Alchemy【贪心,背包】
  9. YbtOJ#853-平面标记【整体二分,凸壳】
  10. Sentry 监控 - Alerts 告警