BFF概念
BFF
BFF(Backends For Frontends)
问题一、BFF承载了过多的业务。从上面的两大块业务功能来看,如果去掉这个BFF,后端是不具备完整的业务能力的。这正是我在《BFF避坑指南》中描述的一个BFF实施常见问题,将BFF实现成了企业级服务总线(ESB)。后端服务只需要具备必要的增删改查接口,BFF就可以完成前端的大部分需求。这样的BFF 以一己之力承载了前端所有的业务,最终一定会走向大泥球,成为架构中的瓶颈和脆弱点。 问题二、后端服务接口设计不是面向业务能力,而是面向数据。在这个事例中,一个BFF接口中要调用3个维修单服务接口才能完成完整的逻辑,维修单服务并没有将完整的业务能力内化在自己的服务内,而是提供了一些可以组合的接口,这也是开发者将大量逻辑写到BFF中的众多原因之一,或者说是BFF这种实践思想的一种后果。 问题三、后端服务间数据关系比较紧密,耦合较重。一个业务状态的更新会涉及三个后端服务数据的更新,这背后的坏味道就是服务间耦合较重,边界不清晰,会导致大量业务功能需要多个服务配合才能完成。 问题四、一个接口完成多次写操作,很难保证数据一致性。任何一个写接口的失败都会中断整个流程,而中断点不同,产生的数据一致性问题也不一样,在不采用分布式事务的情况下,这个接口上线后一旦产生问题,都将是非常棘手的。 问题五、接口逻辑过于复杂,很难保证性能,稳定性差。几十次的跨服务间调用,即便每个调用都是毫秒级响应,这个接口的性能最好也只有几百毫秒,稍有波动就会上升到秒级,甚至更差,很难保证线上的稳定性,在有网络波动或异常的情况下,用户体验极差。
------------------------------BFF的设计原则---------------------- BFF为前端而生,关注点在提升前端用户体验。 BFF不承载业务能力,业务逻辑要下沉到合适的后端服务中。 BFF不承载特定技术能力,必要时可以建立专门的服务承载,如文档打印、Excel生成、算法逻辑等。 BFF不做后端服务的集成层,某个后端服务的数据变更需要同步到其他服务,不能通过BFF实现。 ------------------------BFF治理的主要方向---------------------------- 首先分析BFF问题背后是不是存在后端服务设计问题,优先解决后端服务的设计问题。 从业务上分析BFF接口的职责,保证接口职责单一。 将BFF中业务能力下沉到后端服务。 将BFF中需要复用的技术能力抽取成共享库或下沉建立后端服务。 避免一个BFF接口依赖过多的后端服务,根据系统复杂度来看,最多依赖不超过5个后端服务为宜。 避免一个BFF接口多次写操作,不滥用BFF站在上帝视角所拥有的权利,各司其职。 ----------------------graphql------------------------------- GraphQL 具有如下特性
- 定义数据模型:按需获取
- 数据分层
- 强类型
- 协议而非存储
- 无须版本化
GraphQL 和 REST 对于 GraphQL 和 REST 之间的对比,主要有如下不同:
- 数据获取:REST 缺乏可扩展性, GraphQL 能够按需获取。GraphQL API 调用时,payload 是可以扩展的;
- API 调用:REST 针对每种资源的操作都是一个 endpoint, GraphQL 只需要一个 endpoint( /graphql), 只是 post body 不一样;
- 复杂数据请求:REST 对于嵌套的复杂数据需要多次调用,GraphQL 一次调用, 减少网络开销;
- 错误码处理:REST 能够精确返回HTTP错误码,GraphQL 统一返回200,对错误信息进行包装;
- 版本号:REST通过 v1/v2 实现,GraphQL 通过 Schema 扩展实现; --------------------------------BFF技术栈----------------------------------------- NodeJS/GraphQL/express/docker 我们使用 GraphQL-express 框架构建项目的 BFF 端,然后通过 Docker 进行部署。 BFF 和微服务后台之间,还是通过 registrator 和 Consul 进行服务注册和发现。
业务逻辑还是应该由微服务关心,BFF 关注的是客户端需要什么。
graphql 基于 JavaScript 的 GraphQL 实现
koa v2 Node.js Web Framework 框架
apollo-server-koa 适配 koa v2 的 Apollo Server
data-loader 优化 GraphQL Resolver 内发出的请求
graphql-scalars 提供业务中常用的 GraphQL Scalar 类型
faker 提供基于类型的 Mock 数据 结合 GraphQL Schema 可自动生成 Mock 数据
@graphql-codegen/typescript 基于 GraphQL Schema 生成 TypeScript 文件
graphql-depth-limit 限制 GraphQL Query 的查询深度
jest 单元测试框架 ----------------------------BFF实践的三大问题----------------------------------- 问题一:重复代码 通常情况下我们会为每个不同的前端构建一个BFF,还可能会为一些特定的场景建立BFF(如对第三方系统提供API),不可避免地,多个BFF之间会出现大量的重复代码,比如可能会存在相同的数据转换逻辑,相同的API数据聚合逻辑等等。 问题二:滑向ESB(Enterprise Service Bus,企业服务总线) BFF为了适配前端而生,更关注解决前端的用户体验问题,而真实的业务能力应该由后端服务来承接,而不是BFF。 问题三:性能问题 如果一个BFF接口调用了3个以上接口,那就要警惕了,需要分析下后端服务拆分得合不合理,前端UI展示的数据是否有必要放在一起,否则性能问题会逐渐成为一个不可避免的问题。
参考文章:
跨平台架构:如何设计 BFF 架构系统