译者 | 康少京
审校 | 墨色
策划 | 信远
在过去,应用程序很简单。浏览器向web应用端点发送请求,后者从数据库中获取数据并返回响应。移动客户端的兴起以及与其他应用的集成打破了这种简单性。本文将讨论一种处理复杂性的解决方案。
增加系统架构的复杂性
首先,我们需要对上述简单的体系结构进行建模。
移动客户端改变了这种方法。移动客户端的显示区域更小,例如:平板电脑,手机。有一种可能的解决方案是返回所有数据,并让每个客户端过滤掉不必要的数据。不幸的是,手机客户端也受到带宽不足的影响,并非所有手机都具备5G功能。即使是这样,如果它位于偏僻的地方,连接点只能提供H+,那也没用。
因此,不能过度抓取。每个客户端需要不同的数据子集。使用单体,可以根据每个客户端提供多个端点。
可以设计一个在最前端具有特定层的网络应用程序,该层检测发出请求的客户端,并过滤掉响应中的无关数据,web应用程序中的过度抓取不是问题。
如今,微服务风靡一时,每个人及其邻居都想实现一个微服务架构。
微服务背后是“两个披萨团队”的理念。每个团队都是自主的,负责一个微服务或一个前端应用程序。为了避免开发工作之间的耦合,每个微服务团队发布其API合同并非常谨慎地处理更改。
每个微服务都需要为每种客户端提供严格必需的数据,以避免上面的过度抓取问题。对于少量的微服务,让每个微服务根据客户端过滤数据很麻烦,数量众多,这显然是不可能的,因此,微服务数量与不同客户端数量之间的笛卡尔因子使得每个微服务上的专用数据端点的成本成倍增长。
解决方案:Backend for Front-End
BFF背后的想法是将逻辑从每个微服务转移到一个专用的可部署端点。后者负责:
- 从每个所需的微服务中获取数据
- 提取相关部分
- 聚合它们
- 最后以一种与特定客户相关的格式返回
同一个团队开发客户端及其相关的BFF。BFF提供了与微服务相同的权衡:通过增加系统复杂性来提高开发速度。
独立部署单元与API网关
关于BFF的文献暗示了专用部署单元,如上图所示。有些文章,比如本篇,反对使用API网关的BFF。但概念图不一定与部署图一一对应。
与许多领域一样,人们应该更多地关注组织方而不是技术方面的问题。在这种情况下,最关键的一点是,负责前端的团队也要对BFF负责。无论是单独的部署单元还是API网关配置的一部分,都是一个实现细节。
例如,使用Apache APISIX,每个团队都可以将他们的BFF代码独立部署为单独的插件。
性能考虑
对于单体,情况如下:
- 从客户端到单体的请求需要一个特定的时间T。它经过互联网,T可能很长。
- 与T相比,对数据库的不同内部调用可以忽略不计。
一旦迁移到微服务,客户端就需要依次调用每个微服务。因此,对于顺序调用,时间变为∑(T1、T2、Ti、Tn)。由于这是不可接受的,客户端通常使用并行调用。时间变为最大(T1、T2、Ti、Tn)。注意,即使这样,客户端也需要执行n个请求。
在BFF的情况下,无论实现的是什么,我们都会在T时间内返回一个请求。与单体相比,从BFF到微服务还有额外的请求t1、t2、ti、tn,但它们可能位于一起。因此,整体时间会比单体更长,但由于每个t都比T短得多,因此不会对用户体验产生太大影响。
结论
你可能不应该实现微服务。如果你这样做,微服务不应该返回整个数据,而是让客户端负责清理这些数据。因此,微服务需要根据客户端返回所需的确切数据。它在微服务与客户端之间引入了强耦合。你想移除这个耦合。为实现这一点,Backend For Front-end方法将清理逻辑从每个服务中提取到一个专用组件中,该组件还负责聚合数据。每个客户团队还负责其专用的BFF:当客户更改其数据需求时,团队可以部署适应新需求的新BFF版本。
BFF是一个概念解决方案。没有什么要求提取/清理/聚合逻辑位于特定位置。它可以是专用部署单元,也可以是API网关中的插件。
在之后的文章中,将会展示本文中所描述的不同步骤。
原文链接:https://dzone.com/articles/discussing-backend-for-front-end
译者介绍
康少京,51CTO社区编辑,目前从事通讯类行业,底层驱动开发岗位,研究过数据结构、Python,现对操作系统和数据库等相关领域感兴趣。