骚年快答 | 微服务架构中的BFF到底是啥?

【答疑解惑作者 / Edison Zhou

这是恰童鞋骚年的第263篇原创内容


昨天的骚年快答《技术中台与业务中台都是啥玩意》一文中留下一个问题:BFF是啥?为啥在API网关和业务中台之间加入了一层BFF?考虑到在实际工作中,我的大部分同事都问过这个问题,这里我也总结一下进行答复。

1从一个MyShop开始说起

为了讲清BFF是个啥,这里引用我在波波老师的课程《Spring Boot与K8s云原生应用开发》中学到的一个案例,来跟大家分享一下,并尽力说清楚BFF是啥,又是如何演化出来的。

假设我们在一个开发团队中,开发了一个叫做MyShop的电商项目,它采用的是微服务的架构风格。它经历过几次架构调整,我们就跟着它的调整来看看BFF是怎么演化出来的。

假设v1版本在七八年之前,MyShop已经采用了服务化的架构,它的客户端也主要还是以传统的Web应用为主。在当时,它的SOA架构已经算是跟上了潮流。

转眼之间,来到了四五年前,MyShop升级为了v2版本,它的架构如下图所示:

可以看到,这个时候已经进入了移动互联网时代,MyShop为了紧跟时代,也推出了自己的无线应用App。为了能够尽快上线,MyShop团队的架构师设计了v2架构,它为App端新增了一个Nginx反向代理,可以使App入口直接访问API微服务。

但是,这个急于求成的v2架构存在以下问题:

(1)App端和内部的API微服务存在一个强耦合的关系(包括接口耦合和域名耦合),任何一边的变化都会对另外一边造成一定影响。

(2)每个对外暴露的服务,都需要新的域名,而域名是需要买的,是需要承担成本的。

(3)内部的API微服务一股脑地暴露在了公网上面,存在很大的安全风险。

(4)App客户端需要开发大量的聚合裁剪的逻辑,客户端很重且重复劳动。(所谓聚合裁剪,解释一下,聚合就是一次需要从多个微服务获取数据进行整合使用,而裁剪就是需要对微服务返回的数据进行过滤,可能只会用到其中一部分的字段数据)

2引入BFF的MyShop v2.5

由于v2版本存在的问题太多,于是架构团队决定在Nginx和内部API微服务之间引入一层无线BFF(英文全称:Backend For Frontend,指为前端应用开发的后端服务)来解决这个问题,也就有了下面的v2.5版本的架构。

我们可以将BFF看做是一个后端微服务的代理服务,它主要做聚合和裁剪的逻辑,方便客户端接入和访问。可以看到,引入了BFF之后,降低了App端与后端微服务之间的耦合,从而避免了v2版本提到的强耦合问题。此外,App端只需要知道BFF的域名即可,内部微服务也躲在BFF之后不需要暴露在公网之上。

由于v2.5版本解决了很多问题,因此成功上线,也为MyShop无线业务的发展做了很大的支持。

但是,随着业务的不断快速发展,单块的无线BFF堆积了大量的不同业务线的逻辑变得越来越臃肿,升级维护也变得越来越困难。此外,根据康威法则,单块的无线BFF和多团队也出现了不匹配的问题,即团队之间沟通成本变低,交付成本也就会变高。最后,无线BFF里面除了多业务线的聚合裁剪逻辑,还引入了Cross-Cutting(跨横切面)的逻辑,比如安全认证、日志监控、限流熔断等等。随着时间的推移,代码变得越来越复杂,技术栈越堆越多,开发效率也不断下降。(当然,还有单点问题等等,这里就不多赘述了)

3网关+BFF模式的MyShop v3

为了解决v2.5版本存在的问题,架构团队经过进一步思考,一方面决定将单块的无线BFF进行解耦拆分,针对不同的业务线引入独立的微服务集群。另一方面,决定在无线BFF和Nginx之间再引入一个新的角色:API网关,并将Cross-Cutting的职责转移到API网关上。自此,v3架构出炉,如下图所示:

v3架构下,BFF按照团队或业务线的边界进行划分,每个业务线团队可以并行各自开发和交付BFF。而网关则由单独的中间件或框架团队进行开发和维护,它专注于路由转发和Cross-Cutting层面的功能建设,让业务线团队专注于业务逻辑的开发。

我们.NET程序员所熟知的Ocelot网关项目(对,就是张队参与贡献的那个网关项目),就帮助我们实现了路由转发和Cross-Cutting的功能,例如限流熔断、集中鉴权(例如集成IdentityServer)、负载均衡、调用追踪等。

4乘风破浪的MyShop v4

最近一两年呢,MyShop团队迎来了新的业务和技术的发展需求,要开放内部的企业级能力建设OpenAPI开放平台,还想要借助第三方的力量在MyShop平台上进行创新打造生态从而丰富MyShop的应用形态。此外,SPA单页应用、H5前后端分离应用等多类型的应用客户端也需要接入。架构团队设计了一个如下图所示的v4架构,从而满足快速发展的已有和未来可能的需求:

在v4架构下,移除了原来偏运维层面的Nginx反向代理,转而统一使用可编程性较强的API网关作为客户端应用入口。这里的网关也进行解耦拆分,针对不同的客户端应用场景,分为了四个类型,如开放平台网关、H5网关、无线网关和Web应用网关。而BFF层面,也根据业务线拆分为了无线BFF、H5 BFF及开放平台BFF。整个架构层次清晰,职责分明,是一种灵活的、方便支持MyShop业务快速发展的架构。

相信看到这里,你大概应该明白了BFF是个啥,它在微服务架构中的位置和作用,以及它是如何演化出来的。

画外音:如果还没明白,那就再看一遍!

5我司还处于v3架构阶段

刚刚通过MyShop的案例架构演化,讲解了BFF和网关是如何演化出来的。那么,你可能会问,我司的架构处在哪个阶段。这里,回答一下,还在v3阶段。


可以从这个技术体系图中看到,作为应用服务层的API服务就是BFF,他们会从基础业务服务如客户服务、订单服务、产品服务等微服务中获取数据,进行一定的聚合和裁剪返回个某个具体业务线的前端应用,前端应用可能是SPA也可能是H5应用。BFF层的API服务,我们在实践中大部分都使用了ASP.NET Core进行开发,同时也在尝试使用Go进行开发,也让前端有兴趣的同事引入进来用Go进行BFF的开发。但是,在基础服务层面即前面所说的业务中台层,还是由后端同事使用ASP.NET Core开发,确保质量。

API网关层面,我们使用的是Ocelot,集成了鉴权认证等工作,前端统一只需要记住网关的域名即可,带上合法的token访问即可获取数据返回。很多人说Ocelot性能低建议使用Kong,但是我司业务量小啊,所以目前没啥问题,用得好好的。内部微服务之间的相互调用,我们目前也是走了API网关(区别于外部应用访问的网关,这里我称之为内部网关),不过为了方便(其实是懒),我们对于内部信任的服务间调用,没有走JWT认证,当然也可以选择Client Credentials(客户端凭证)模式。

对于现阶段的我们的架构来说,只能说是够用,因为业务量真的不大,也没必要为了上所谓的高性能高可用架构做过多的设计,对传统家居装饰行业的企业来说,IT先满足业务支持业务快速发展吧。传统行业的企业数字化转型,也并不是一次就吃个胖子,慢慢演进吧。

最后,想着是快答,居然也洋洋洒洒写了这么多,希望对你有所帮助吧!

画外音:如果看到这里,你都不点个赞/在看,有点那啥了...

往期精彩快答

技术中台与业务中台到底是啥?

点个“在看” 就是对我最大的支持

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/308835.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Visitor(访问者)--对象行为型模式

Visitor(访问者)–对象行为型模式 一、意图 表示一个作用于某个对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 二、动机 1.在软件构建过程中,由于需求的改变,某些类层次结构中常…

骚年快答 | 技术中台与业务中台都是啥?

【答疑解惑】| 作者 / Edison Zhou这是恰童鞋骚年的第262篇原创内容最近有童鞋在我之前发布的《聊聊中台》一文中提问:技术中台是什么?和业务中台又有什么区别?考虑到在工作中,也有部分同事问过这个问题,我这里总结一下…

[mybatis]映射文件_参数处理_#和$取值区别

#{}:可以获取map中的值或者pojo对象属性的值${}:可以获取map中的值或者pojo对象属性的值 区别: #{}:是以预编译的形式,将参数设置到sql语句中,相当于原生jdbc的PreparedStatement;防止sql注入${…

平台or职位,你怎么选?

这里是Z哥的个人公众号每周五11:45 按时送达当然了,也会时不时加个餐~我的第「150」篇原创敬上大家好,我是Z哥。这周有位小伙伴和我聊到一个问题,选择工作的时候是平台重要还是职位重要?我想,很…

闲谈设计模式

闲谈设计模式Intro设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。了解这些前辈们总结出来的经验有助于帮助你写出来更优秀的代码,帮助你写出可扩展、可读、可维护的高质量代码。在极客时间里推出…

[mybatis]log4j

引入依赖&#xff1a; <dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency>在资源文件下写一个log4j配置文件: <?xml version"1.0" encoding"UT…

eShopOnContainers 知多少[11]:服务间通信之gRPC

1. 引言最近翻看最新3.0 eShopOncontainers源码&#xff0c;发现其在架构选型中补充了 gRPC 进行服务间通信。那就索性也写一篇&#xff0c;作为系列的补充。2. gRPC老规矩&#xff0c;先来理一下gRPC的基本概念。gRPC是Google开源的RPC框架&#xff0c;比肩dubbo、thrift、brp…

[mybatis]映射文件_参数处理_#取值时指定参数相关规则

jdbcType通常需要在某种特定的条件下被设置&#xff1a; 在我们数据为null的时候&#xff0c;有些数据库可能不能识别mybatis对null的默认处理。比如Oracle&#xff08;报错&#xff09;&#xff1b;jdbcType OTHER&#xff1a;无效的类型&#xff1b;因为mybatis对所有的null映…

龙芯开源社区上线.NET主页

龙芯团队从2019年7 月份开始着手.NET Core的MIPS64支持研发&#xff0c;经过将近一年的研发&#xff0c;在2020年6月18日完成了里程碑性的工作&#xff0c;在github CoreCLR 仓库&#xff1a;https://github.com/gsvm/coreclr&#xff0c; 随后受到.NET社区的很大参与热情鼓舞之…

[mybatis]映射文件_select_返回集合(List,Map)

select返回List public interface EmployeeMapper {public List<Employee> getEmpsByLastNameLike(String lastName);}<!-- public List<Employee> getEmpsByLastNameLike(String lastName);--><!--resultType;如果返回的是一个集合&#xff0c;要写集…

免费 | 数千个 Azure 官方高清矢量图标大放送!

点击上方关注“汪宇杰博客” ^_^导语我们平时绘制云应用架构图时&#xff0c;经常要用 Azure 各项服务的图标。不知各位会自己去截图&#xff0c;还是在浏览器 F12 里使劲抠图&#xff1f;是不是做PPT 5分钟&#xff0c;扣图2小时&#xff1f;现在用不着自己使劲啦&#xff0c;…

使用sqlserver搭建高可用双机热备的Quartz集群部署

一般拿 Timer 和 Quartz 相比较的&#xff0c;简直就是对 Quartz 的侮辱&#xff0c;两者的功能根本就不在一个层级上&#xff0c;如本篇介绍的Quartz强大的集群机制&#xff0c;可以采用基于sqlserver&#xff0c;mysql的集群方案&#xff0c;当然还可以在第三方插件的基础上实…

从Memcached到Redis,从RabbitMQ到Kafka,为了高并发,这些年我们不容易!

周一上班又撕了一页台历&#xff0c;随即心里头却是一惊。如今高考落下帷幕&#xff0c;不曾想2020竟已过了一半&#xff01;这一年又是疫情又是洪水&#xff0c;我们的目光被各种重大事件所吸引&#xff0c;此时审视一下自己&#xff0c;突然觉得不踏实了&#xff01;一场疫情…

[mybatis]动态sql_if_where_trim判断OGNL

OGNL if 要求&#xff1a;查询员工&#xff0c;要求&#xff0c;携带了哪个字段查询条件就带上这个字段的值 //携带了哪个字段查询条件就带上这个字段的值public List<Employee> getEmpsByConditionIf(Employee employee);<!-- public List<Employee> getEm…

[mybatis]动态sql_choose_分支选择

choose 如果带了id就用id查&#xff0c;如果带了lastName就用lastName查&#xff1b;只会进入其中一个 public List<Employee> getEmpByConditionChoose(Employee employee);<!-- public List<Employee> getEmpByConditionChoose(Employee employee);-->…

7.15周三晚8点,dotnet课堂全新起航,张善友/陈计节/刘腾飞我们一起来聊聊abp的故事...

直播主题&#xff1a;我们和Abp的故事直播嘉宾&#xff1a;张善友&#xff0c;陈计节&#xff0c;刘腾飞直播话题张善友&#xff1a;我是如何使用Abp的刘腾飞&#xff1a;利用Abp的模块化解决单体和分布式混合架构陈计节&#xff1a;Abp开源项目的DevOps实践Abp VNext 处于被低…

ASP.NET Core端点路由 作用原理

端点路由(Endpoint Routing)最早出现在ASP.NET Core2.2&#xff0c;在ASP.NET Core3.0提升为一等公民。Endpoint Routing的动机在端点路由出现之前&#xff0c;我们一般在请求处理管道的末尾&#xff0c;定义MVC中间件解析路由。这种方式意味着在处理管道中&#xff0c;MVC中间…

程序员修神之路--分布式系统设计理念这么难学?

点击“蓝字”关注我们吧福利&#xff1a;有件小事想和大家说一下菜菜哥&#xff0c;问你个问题&#xff0c;为什么现在的系统都设计为分布式系统呢&#xff1f;这个问题问得好&#xff0c;就像为什么程序员会慢慢脱发一样神奇01PART分布式系统身为二十一世纪的一名程序员&#…

使用keepalived搭建双机热备高可用一览

很多时候大家为了部署高可用方案都是前端配一个 nginx&#xff0c;如果nginx挂掉怎么办&#xff0c;比如下面这张图&#xff1a;你可以清楚的看到&#xff0c;如果 192.168.2.100 这台机器挂掉了&#xff0c;那么整个集群就下线了&#xff0c;这个问题该怎么解决呢&#xff1f;…

Linus通过了Linux中避免master/slave等术语的提案

Linux 内核维护者 Dan Williams 曾于 7 月初提交一份提案&#xff0c;建议逐步取消 master/slave 和 blacklist/whitelist 术语。近日&#xff0c;Linus Torvalds 则在 Linux 5.8 版本库的拉取请求中批准了该提议。自此&#xff0c;Linux 开发人员则需要使用新的术语来替代 mas…