系统设计 | "胖瘦" BFF:常见的两种微服务形态
文 | 少个分号 (转载请注明出处)
公众号:DDD 和微服务
知乎:少个分号
微信号:shaogefenhao
网站:shaogefenhao.com
微服务架构中的一些概念非常模糊,业界往往没有取得共识。对于应用来说,其原因是业务背景多种多样,往往单一的模式不能满足现实需要。个人认为这是架构意识形态之争的根本原因。
今天来辨析一下微服务架构中 BFF,其含义和两种架构形态。
胖瘦 BFF 之争
我自 2015 年开始参与的所有应用系统都是服务化的了,都算比较大型的系统,这可能是解决大型复杂应用的必然之路。
在服务化的系统中规划阶段,有一些必然会被讨论的话题:
要不要 BFF?要不要编排层?要不要网关?什么是网关?应用网关和网关的区别是什么?后端(领域服务)服务之间要不要互相调用?要不要使用 BFF 来编排后端服务?BFF 是不是编排层?BFF 能不能宏观上对应 DDD 的应用层?
在这些问题中,最显著的问题倒不是用来接用户流量的服务叫什么名字,而是它应该直接转发数据还是需要为每个 API 重新编写一次实现,并调用后端 API。
其结论会决定我们在 BFF 中是否编写大量代码,所以我把它们的区别称之为"胖瘦 BFF"。不同 BFF 的考量会决定微服务架构的两种形态。
在开始讨论 BFF 之前,我们先对齐一下语言。
目前还比较少关于微服务架构的标准,我参考了中国通信标准化协会发布的 《分布式应用架构通用技术能力要求 第 1 部分:微服务平台》中的概念"应用服务"来代表 BFF。
BFF 的全称为:Backend for Frontend,意思是由于微服务众多,需要一个统一入口作为前端集成使用,这类服务我们一般叫做 BFF。
其实这类入口服务有很多种称呼,我所知或者听到的就有:
BFF
编排层
编排服务
应用网关
服务网关(通信协会标准中使用的名称)
Portal API (意思是系统的不同入口)
前台(一些电商系统喜欢这么叫,区别于后台、领域服务、Domain Service 或者中台)
Experience/User API (用于用户体验使用的 API)
在本文范围内暂且使用 BFF 吧。
胖 BFF
在有一些架构中形态中,BFF 会有以下职责:
鉴权
限流、熔断、服务降级、灰度路由等
接入多种协议和设备,比如 MQTT 服务、WebSocket 等
编排领域服务,尽量避免后端服务之间互相依赖,统一由 BFF 处理
不同类型的客户端一套 BFF
非常接近 DDD 四层架构中的应用层,处理面向场景的业务
为了区分另外一种相反的架构思路,我暂且叫做胖 BFF,因为它的职责比较多。
胖 BFF 的好处是:
可以对不同类型的客户端定制一套 API,且各自之间不受干扰
领域服务可以设计得比较原子化,比较少的侵入特定场景信息到领域服务中
容易适配更多类型的客户端
比较容易实现个性化的鉴权、特定用户群的交互逻辑
方便实现准确、统一的 API 文档
但是这类架构也有非常多的弊端,导致很多架构师非常抗拒:
破坏了端到端交付能力,如果按照上下文划分微服务,刚好这些微服务和前端业务和需求对应,那么跨功能团队的交付效率会更高
重复劳动,一些接口的模型不仅在领域服务实现一次,还需要在 BFF 做一次
难以分工,维护后端服务的人员都会和这个服务集成
在海外的一些文章和书籍中,他们也会有类似的困惑。很多架构师把这种结构叫做编排(Orchestration),而相对的就是 BFF 仅仅扮演转发的作用,我将其成为“瘦 BFF”,也就成了我们口中的网关,有时候被称为 Choreography 架构,中文是编舞。
瘦 BFF
瘦 BFF 可以等同于 Choreography 架构,其职责可能更少:
鉴权
透明转发流量到后端服务
和胖 BFF 类似,也有限流、熔断、服务降级、灰度路由等职责
它的好处是:
端到端交付,前端开发人员直接使用后端领域服务的 API 文档
开发效率高,避免多编写一层 BFF
减少一次集成
对应的,它的弊端可想而知:
没有编排层,服务之间相互依赖
编排行为落入前端或者领域服务,拓展性差
领域服务之间调用关系复杂
领域服务职责过多,侵入业务场景,难以被复用
两种形态对比
我们把这两种常见的架构放到一起如下所示:
Design Pattern 1 的架构中,对不同的来源请求都使用了各自的入口服务承接,这种结构成本很大,但是对于接入渠道多样的系统来说非常适合。
Design Pattern 2 的架构中,前端直接调用后端服务,忽略掉了 BFF,适合接入差异较小的应用。
权衡
那么在什么场景下,更合理的选择这两种结构之一呢?
受到不同业务场景的影响,这就是不同架构师之间不同意见的由来。 我和很多人交流过这个问题,他们都有各自的偏好,而且都觉得理所当然。
对于电商、互联网产品的开发者来说,他们会觉得胖 BFF 架构非常自然,甚至会觉得为什么会有公司连 BFF(或者说前台)都不要。如果没有胖 BFF,如何应对多种多样的用户群和客户端将是一个难题。
以互联网金融产品为例,他们的业务渠道非常多:APP、第三方集成、官网、代理商后台、管理后台等,这些渠道的接入方式多种多样,甚至可以看做不同的产品。
但是,以企业内部使用的应用系统来说,即使用户规模非常大,但是他们的用户群非常固定、交互方式统一、数据权限能找到规律,这类应用做起来就会发现胖 BFF 中写了非常多重复代码。
不过,唯一例外的是,对于企业内部应用来说,在系统集成方面又会变得多种多样。那么对于用户侧的 BFF 来说可以简化,对于 Open API 中的逻辑往往省略不掉,Open API 作为系统防腐层,非常有必要设计为具有编排能力的 BFF。
总结
无论是胖瘦 BFF,其实都是基于场景对单体系统拆分的结果。因此非常取决于所属场景,并选择一个能忍受其缺点的技术方案。
正是由于应用开发中需求的多样性,我们还不能找到一个一劳永逸的技术架构,这也解释了为什么目前还没有形成统一的技术方案和观念。
参考资料
微服务的结构 https://shaogefenhao.com/libs/webinar-notes/java-solution-webinar-3.html
https://medium.com/gbtech/orchestration-pattern-3d8f5abc3be3
https://orkes.io/blog/why-is-microservice-orchestration-important-now
https://medium.com/geekculture/microservices-orchestration-vs-choreography-technology-5dbe612cf7e9
版权声明: 本文为 InfoQ 作者【少个分号】的原创文章。
原文链接:【http://xie.infoq.cn/article/9d11a6f8572c6334b3b6ae8fd】。文章转载请联系作者。
评论