介绍
BFF(Backend for Frontend)和网关Gateway是微服务架构中的两个重要概念,这两个概念相对比较新,有些开发人员甚至是架构师都不甚理解。
本文用假想的公司案例+图示的方式,解释BFF和网关是什么,它们是怎么演化出来的。希望对架构师设计和落地微服务架构有所启发。
服务化架构V1
我们先把时间推回到大致2011年左右。假设有一家有一定业务体量的电商公司CoolShop,在这个时间点它已经完成单块应用的解构拆分,内部SOA服务化已经初步完成。这个时候它的无线应用还没有起步,前端用户体验层主要是传统的服务端Web应用,总体服务化架构V1如下图所示。
服务化架构V2
时间转眼来到2012年初,国内的无线应用开始起风,CoolShop公司也紧跟市场趋势,研发自己的无线原生App。为了能尽快上线,公司的架构师提出如下V2架构,让App直接调用内部的服务:
这个架构有如下问题:
无线App和内部微服务强耦合,任何一边的变化都可能对另外一边造成影响。
无线App需要知道内部服务的地址等细节。
无线App端需要开发大量的聚合裁剪和适配逻辑:
聚合:某一个功能需要同时调用几个后端API进行组合,比如首页需要显示分类和产品细节,就要同时调用分类API和产品API,不能一次调用完成。
裁剪:后端服务返回的Payload一般比较通用,App需要根据设备类型进行裁剪,比如手机屏幕小,需要多裁掉一些不必要的内容,Pad的屏幕比较大,可以少裁掉一些内容。
适配:一种常见的适配场景是格式转换,比如有些后台服务比较老,只支持老的SOAP/XML格式,不支持新的JSON格式,则无线App需要适配处理不同数据格式。
随着设备类型的增多(iPhone/Android/iPad/WindowsPhone),聚合裁剪和适配逻辑的开发会造成设备端的大量重复劳动。
服务化架构V2.1
V2架构问题太多,没有开发实施。为解决上述问题,架构师经过思考决定在外部设备和内部微服务之间引入一个新的角色~Mobile BFF。
所谓BFF其实是Backend for Frontend的简称,中文翻译是为前端而开发的后端,它主要由前端团队开发(后端微服务一般由后端团队开发)。BFF可以认为是一种适配服务,将后端的微服务进行适配(主要包括聚合裁剪和格式适配等逻辑),向无线端设备暴露友好和统一的API,方便无线设备接入访问后端服务。
新的V2.1架构如下图所以:
这个架构的优势是:
无线App和内部微服务不耦合,通过引入BFF这层间接,使得两边可以独立变化:
后端如果发生变化,通过BFF屏蔽,前端设备可以做到不受影响。
前端如果发生变化,通过BFF屏蔽,后端微服务可以暂不变化。
当无线App有新的需求时,通过BFF的屏蔽,可以减少前后端团队的沟通协调开销,很多需求由前端团队在BFF上就可以自己搞定。
无线App只需要知道Mobile BFF的地址,并且服务接口是统一的,不需要知道内部复杂微服务的地址和细节。
聚合裁剪和适配逻辑在Mobile BFF上实现,无线App端可以大大简化瘦身。
服务化架构V3
V2.1架构比较成功,实施落地以后支持了CoolShop公司早期无线业务的成长。随着业务量进一步增长,投入无线研发的团队也不断增加,V2.1架构也逐渐暴露出如下问题:
刚开始只有一个Mobile BFF,是个单块,但是无线研发团队在不断增加,分别对应多条业务线。根据康威法则,单块的无线BFF和多团队之间就出现不匹配问题,团队之间沟通协调成本高,交付效率低下。
Mobile BFF里头不仅有各个业务线的聚合/裁剪/适配和业务逻辑,还引入了很多跨横切面逻辑,比如安全认证,日志监控,限流熔断等。随着时间的推移,代码变得越来越复杂,技术债越堆越多,开发效率不断下降,缺陷数量不断增加。
Mobile BFF集群是个失败单点(Single Point of Failure),严重代码缺陷或者流量洪峰可能引发集群宕机,所有无线应用都不可用。
为了解决上述问题,架构师经过思考决定在外部设备和内部BFF之间再引入一个新的角色~API Gateway,新的架构V3如下图所示:
新的架构V3有如下调整:
BFF按团队或业务线进行解耦拆分,拆分成若干个BFF微服务,每个业务线可以并行开发和交付各自负责的BFF微服务。
网关(一般由独立框架团队负责运维)专注跨横切面(Cross-Cutting Concerns)的功能,包括:
路由,将来自无线设备的请求路由到后端的某个微服务BFF集群。
认证,对涉及敏感数据的API访问进行集中认证鉴权。
监控,对API调用进行性能监控。
限流熔断,当出现流量洪峰,或者后端BFF/微服务出现延迟或故障,网关能够主动进行限流熔断,保护后端服务,并保持前端用户体验可以接受。
安全防爬,收集访问日志,通过后台分析出恶意行为,并阻断恶意请求。
网关在无线设备和BFF之间又引入了一层间接,让两边可以独立变化,特别是当后台BFF在升级或迁移时,可以做到用户端应用不受影响。
在新的V3架构中,网关承担了重要的角色,它是解耦拆分和后续升级迁移的利器。在网关的配合下,单块BFF实现了解耦拆分,各业务线团队可以独立开发和交付各自的微服务,研发效率大大提升。另外,把跨横切面逻辑从BFF剥离到网关上去以后,BFF的开发人员可以更加专注业务逻辑交付,实现了架构上的关注分离(Separation of Concerns)。
服务化架构V4
业务在不断发展,技术架构也需要不断的调整来应对需求的变化。近年,CoolShop公司技术团队又迎来了新的业务和技术需求,主要是:
开放内部的业务能力,建设CoolShop Open API平台。借助第三方社区开发者的力量,在CoolShop平台上进行创新,进一步拓宽CoolShop的应用和业务形态。
废弃传统的服务端Web应用模式,引入前后分离架构,前端采用H5单页等技术给用户提供更好的体验。
为满足业务需求,架构师对服务化架构又进行了拓展升级,新的V4新架构如下图所示:
V4整体思路和V3类似,只是拓展了新的接入渠道:
引入面向第三方开放API的BFF层和配套的网关,支持第三方开发者在CoolShop Open API平台上开发应用。
引入面向H5应用的BFF层和配套的网关,支持前后分离和H5单页应用模式。
V4是一个比较完整的现代微服务架构,从外到内依次分为:端用户体验层->网关层->BFF层->微服务层。整个架构层次清晰,职责分明,是一种灵活的能够支持业务不断创新的演化式架构。
结论
在微服务架构中,BFF(Backend for Frontend)也称聚合层或者适配层,它主要承接一个适配角色:将内部复杂的微服务,适配成对各种不同用户体验(无线/Web/H5/第三方等)友好和统一的API。聚合裁剪适配是BFF的主要职责。
在微服务架构中,网关专注解决跨横切面逻辑,包括路由、安全、监控和限流熔断等。网关一方面是拆分解耦的利器,同时让开发人员可以专注业务逻辑的实现,达成架构上的关注分离。
端用户体验层->网关层->BFF层->微服务层,是现代微服务架构的典型分层方式,这个架构能够灵活应对业务需求的变化,是一种支持创新的演化式架构。
技术和业务都在不断变化,架构师要不断调整架构应对这些的变化,BFF和网关都是架构演化的产物。
什么是 BFF
BFF,即 Backend For Frontend(服务于前端的后端),也就是服务器设计 API 时会考虑前端的使用,并在服务端直接进行业务逻辑的处理,又称为用户体验适配器。BFF 只是一种逻辑分层,而非一种技术,虽然 BFF 是一个新名词,但它的理念由来已久。
BFF 解决了什么问题
如下图,在我们的前端页面时常存在,某个页面需要向 backend A、backend B 以及 backend C…… 发送请求,不同服务的返回值用于渲染页面中不同的 component,即一个页面存在很多请求的场景。
此时,每次访问该页面都需要发送 3 个请求。同时为了保障 Android,iOS,以及 Web 端的不同需求,需要为不同的平台写不同的 API 接口,而每当值发生一些变化时,需要 Android,iOS,Web 做出修改。与此同时,当我们需要对一个字符串进行处理,如限定 140 个字符的时候,我们需要在每一个客户端(Android,iOS,Web)分别实现一遍,这样的代价显然相当大。
于是,我们就需要 BFF 作为中间件。在这个中间件上我们将做一些业务逻辑处理:
而当我们有了 BFF 这一层时,我们就不需要考虑系统后端的迁移。后端发生的变化都可以在 BFF 层做一些响应的修改。
例如,我们加入 BFF 层,原本每次访问发送 3 请求页面,变成一个请求。
使用 BFF 的正确姿势
- 多端应用
我们在设计 API 时会考虑到不同设备的需求,也就是为不同的设备提供不同的 API,虽然它们可能是实现相同的功能,但因为不同设备的特殊性,它们对服务端的 API 访问也各有其特点,需要区别处理。 - 服务聚合
随着微服务的兴起,原本在同一个进程内运行的业务流程被拆分到了不同的服务中。这在增加业务灵活性的同时,也让前端的调用变得更复杂。BFF 的出现为前端应用提供了一个对业务服务调用的聚合点,它屏蔽了复杂的服务调用链,让前端可以聚焦在所需要的数据上,而不用关注底层提供这些数据的服务。 - 非必要,莫新增
我们在看到 BFF 带来的各种好处的同时,也要注意到它所带来的代码重复和工作量增加方面的问题。如果与已有 BFF 功能类似,且展现数据的要求也相近的话,一定要谨慎对待新增 BFF 的行为。因此,建议非必要,莫新增。