首页 > 编程知识 正文

困局经济学,囚徒困境模型

时间:2023-05-06 05:19:10 阅读:59870 作者:4455

标题BFF的困境与思考1、BFF在整体微服务体系结构中的位置2、BFF是什么1、前端和BFF服务由同一团队负责2、BFF层足够薄3、BFF有明确的服务终端3、BFF服务器按模块划分3、按终端划分4、BFF困境1 .如何划分业务2 .如何平衡代码复用和资源利用率3 .如何避免平面呼叫或交叉呼叫五、BFF划分的原则所有终端都必须与BFF服务对接2 .按[方案]终端模块划分的一个产品可以有一个或多个BFF服务3 .根据[方案]产品中长期终端UI的差异进行划分4. [方案APP,在小程序中尽量保持服务状态6、BFF层码复用原则1 .提取到网关层2 .提取公共包3 .服务下沉到域7、 迈向BFF层的破局者1:server BFF层破局者GraphQL 1. GraphQL是规范2. GraphQL是统一的数据接口3. GraphQL带来的好处4. GraphQL的困境5. Duo-GraphQL

BFF的困境与思考1、BFF在整体微服务体系结构中的位置

微服务化带来的最大问题是服务边界的划分。 可以从纵向职能和横向业务划分两个维度来看。

纵向上,BFF可以相对容易地在网关和域服务之间确定,起到桥梁作用,快速支持前端迭代; 二是让下游领域的服务更加纯粹。

横向分隔是最大的难点,后面有分析。

上图是我们目前的服务架构图,这样的分层并不是最合理的,只是文章后面的铺垫。 从上到下为前端服务、BFF服务、域服务(部分为域聚合和域服务)、中间办公室服务(基础服务)。

二、什么是BFF

为前端后端提供服务。 在后台服务和前端之前添加层,主要是为了快速跟踪UI迭代,从后台提取数据,封装数据,减少对前端的依赖,提高集中力。

为了实现这些,BFF必须遵循一些规则:

1 .前端和BFF服务由同一团队负责,可以更高效地沟通和资源协调,快速响应迭代,同时减少协作过程和依赖。

2.BFF层不负责业务的实现,只应该负责最基本的参数检查、数据调用、组装。 其他逻辑可以浮在网关层(如认证和用户会话)上,也可以降级到后台服务。 后台服务处于域设计模式DDD时,还可以有效防止乱窜,使服务更加有序。

3 .如果为每个BFF层创建一个具有明确服务终端的BFF层,则必须明确其上游是哪个(或多个)终端。 安卓/IOs/web/H5 /小程序…明确的服务终端可以更好地设计BFF层的功能。 减小BFF层,便于维护,便于提供特定能力。 不需要考虑兼容性太宽的设备。

当然,还有其他一些基本原则,比如rest风格的接口、JSON结构数据等,应该尽量暴露通用的接口。

三、BFF服务如何划分纵向划分非常简单,但横向划分并不是那么简单。 首先,您可以知道以下三种划分方法:

1 .按产品分割BFF层。 这是刚分离前后端时喜欢使用的模式。

优点:

接口复用、代码复用、每个终端数据整合服务器资源利用率高的缺点:

接口数据冗馀。 在某些情况下,可能需要端到端匹配。 APP的接口经常还需要版本兼容性。 维护成本高,多个团队联合开发容易发生冲突。

2 .每个模块划分一个产品规模较大,多个团队协同完成时,一个BFF服务实现整个产品功能的可能性较低,在这种情况下,产品的每个模块划分BFF服务的可能性较大。

一个模块使用一个BFF服务支持一个产品的不同端。 这样做的好处是可以降低大型BFF服务带来的复杂性,但实际上没有太大的变化,只是减小了BFF的规模。优点:

按产品模块划分,功能更集中,有利于团队分工。 代码重用率仍然为缺点:

有时依然支持多个终端

3 .基于终端的BFF的第一个概念实际上是基于终端的。 但是,存在一个BFF服务是一个,还是对应于多个终端的问题。 这个暂时不要烦恼。 关于BFF区分的推荐原则问题将在后面叙述。

优点:

快速响应终端迭代支持终端区分功能终端之间的兼容性问题缺点:

各终端BFF中存在重复代码、重复劳动。 容易导致数据不一致。 服务器资源利用率低。

四、BFF困境1 .服务如何划分上面的BFF服务划分只是来自不同维度的讲解,但在实际工作中通常没有这么简单直接。 在许多情况下,如果一个产品的终端太多,模块太多,只需按产品、模块或终端进行分类就很明显了

得很不协调。但又无法提供一个更明确的划分方法,所以最终还是将划分的重任落在“经验丰富”的开发者身上,这明显是不靠谱的一件事(不同的人可能会有不同的划分方法)。

2. 代码复用和资源利用率如何平衡

架构设计没有银弹,只有适合的。所以在代码复用和资源利用率上,往往会与灵活、自主性相违背,就像CAP原则一样,只能取其二而舍其一。

3. 如何避免平级调用或跨级调用

BFF层为了保持它的独立性,禁止BFF之间调用(即是平级调用)。BFF只对自己明确的终端负责,不关心周边的产品/终端。特别是按终端划分时,往往不同端的页面是比较接近的,开发人员有时为了省事,会直接调用“拿”其它端的接口来用,这应该是明令禁止的!

五、BFF拆分的原则

以下是我们公司制定的一些BFF拆分原则,供大家参考:

1. [强制]所有终端必须与BFF服务对接

如果UI直接调用底层服务(领域服务或基础服务),会造成领域服务或基础服务无法稳定,经常需要跟随UI变动。所以每个前端必须有BFF层,这时条红线。BFF存在的目的,除了快速响应前端迭代外,还有一个目的是为了隔离前端后端,让后端更稳定,有沉淀。

2. [建议]按终端 + 模块划分,一个产品可以有一个或多个BFF服务

一个产品比较大时,需要按终端划分,同时还需要按模块划分。这个还取决于各自公司使用的技术栈,如果使用容器,分服务的成本会显示小很多,次之是虚拟机,再次之是直接在物理机上。

3. [建议]按产品中长期终端UI的差异性拆分

这应该是最重要的一条拆分原则了。按终端拆分并不是每一个端都需要一个BFF服务,这样会有太多的服务,不利于维护。BFF原则上是跟着UI走的,无论是哪个端的UI,如果差异性不大,rzdgq对接同一个BFF服务。UI差异性体现在:

展示的数据和数据逻辑。如果不同终端,展示的数据和取数据逻辑是一致的,那么从同一个接口取数据完全没有问题。终端功能。不同的终端,可以提供的用户交互是完全不一样的,比如app可以直接拨打电话,而PC端是无法做到,而提供二维码,让手机扫码拨号,这就是很大的差异性。原生app能够提供顺滑的切换页面的交互,而H5很难做到,app有推送…

(大的产品,可以按终端 + 模块来划分BFF) 4. [建议]尽量为APP、小程序提供最终的数据

APP、小程序的更新需要发版,有的还需要审核,所以更改成本很高。如果在BFF层提供足够保真的数据(比如UI上显示的金额,小数点保留几位;比如一个列表的排序等,直接在BFF计算好直接吐给APP),能够快速的修改BFF的数据而快速更新APP、小程序上的数据,不用发版。

5. [建议]尽量保持服务无状态

这其实是微服务的设计原则。无状态即是可以自由水平扩展,而不需要去同步、维护一些状态,比如用户的登录态;用户的会话等。

六、BFF层代码复用原则 1. 向上网关层抽取

用户的登录态、会话,应该抽取到网关层。而BFF层只保留与底层用户服务的注册、登录、查询通道(通用网关甚至可以不需要)。

2. 抽取公共包

只有一种情况可以抽取公共包在不同的BFF服务间共用,那就是抽取的功能应该是完全没有业务逻辑的,比如Utils包。注意,==公共库通常是耦合的主要原因。==所以要抽取公共库时,必须非常小心,更多时候应该考虑开源社区是否已经有类似的包了。

3. 向下领域服务下沉业务

公共的业务代码不能向上或平行抽取,最好的解决方案是向底层的领域服务下沉业务能力。向下沉,直接面对的是领域服务,所以下沉到哪个地方,怎样下沉直接遵循DDD原则。这样不会把底层服务搞乱,也会越来越规整。

七、BFF层破局者一:Serverless


  Serverless的概念越来越火,但是什么是Serverless呢?上图是AWS lambda的经典应用,开发者不需要再关心服务器,不需要关心内存、CPU、磁盘空间…所有这些,都交给云计算去完成。
  
  Serverless是云计算基金会下面的产品之一,它的定义是提供了其中一种或同时提供两种以下服务:
  FaaS(Functions-as-a-Service) – 用户自己提供的
  BaaS(Backend-as-a-Service) – 三方提供的
  说白了就是把某些接口包装成sdk,以函数或本地方法的方式提供云端的计算能力,这个能力可以是三方提供或用户按照云端的规范自己写,然后发布到云端。
  那么,这是不是一个完美的BFF层实现呢?不一定!

它没有根本上改变BFF层的,至多是把服务/接口的概念打破了,以函数的方式提供。引入了另外的复杂度,比如函数包(serverless也是以引入包的方式来提供对应的函数服务的),同样避不开版本和底层服务(函数)调用的问题。云原生。如果是新项目,倒是个不错的技术选型,不过一旦开始,可能后面就得一直依赖这朵云了。Serverless 更多是云厂家的卖点。 八、BFF层破局者二:GraphQL

1. GraphQL是一种规范

它定义了:

统一的图(图可以理解为一个业务实体对象,以及它们的关联关系)统一的数据逻辑(图的每个类型、字段都需要定义它们的取数据逻辑)统一的查询语法(有点像SQL,一种查询语言) 2. GraphQL是统一的数据接口

所有的数据都是由一个统一的http接口提供。使用gql语法,将页面需要的数据一次性查询出来。不多不少,一来减少http请求;二来不会有多余数据;三者可以UI的变换可以快速修改查询脚本实现。

3. GraphQL带来的好处

领域:
  在BFF层几乎看不到领域的概念,所有的数据都是按UI所需进行拼装。所以GraphQL的出现算是眼前一亮,简直就是BFF的一股清流呀。
  领域对象很重要,它是对象的定义,在哪里出现含义都是一样的。特别是配合GraphQL的关联特性,可以将需要的数据都关联出来,这也是GraphQL的魔力所在,拼数据在GraphQL里面是不存在的!

成本
  GraphQL不需要考虑拆分的问题,因为它就是集中管理的。另外,对于开发人员来说,如果底层服务也是使用DDD,那用GraphQL简直就是爽得不要不要的,因为它不需要再去定义领域了,拿来即用…
  从运维角度来说,也是一种高效的部署方式,还节约网络成本。

监控
  GraphQL的特色之一,监控粒度可以细到字段。字段取值耗时、字段是否有被使用等一目了然。这对于需要下线的字段来说,是个非常有用的工具。

4. GraphQL的困境

把GraphQL吹上天了,那么GraphQL是否就真的是个灵丹妙药呢?为什么现在用的企业并不是很多呢?
  确实,GraphQL的初衷很好,但是在具体实施的时候却有很多的问题,主要是:

维护图的成本很高
  定义图,需要对业务、对UI的把握非常到位,不然再好的东西,没有设计好,最后也会变成一团糟。图的定义说白了就是领域模型、领域能力的定义。
  另外,多个团队维护同一个产品时,分工协作也是一个很大的问题。

维护数据逻辑成本很高
  图中的每个类型、字段取值都需要指定,比如从API中取…
  GraphQL在定义之初是无法知道会被怎样使用的,而是由GraphQL引擎自动完成,虽然一些GraphQL引擎的实现中帮你准备了很多性能优化策略,但是最终还是需要人工去定义。很容易出现循环调用PRC、N+1等性能问题。
  即便是当前已经商业化了的Apollo GraphQL,也躲不开这两大块问题。

5. Duo-GraphQL

把GraphQL吹上天,接着又泼了盆冷水,还让不让人愉快地玩耍了?
  这里介绍一个Java的GraphQL实现:Duo-GraphQL,它是github上的一个开源项目,基于apache-2.0协议开源,是个很有意思的项目。
 
看看它提供的主要功能:

由普通的RESTful服务实现自动生成Schema,即图的维护是自动的自动绑定Type / Field的数据逻辑自动实现了多种性能优化。比如合并请求、自动解决N+1问题、智能缓存等

Duo-GraphQL保留了GraphQL的所有优势,自动化完成了GraphQL的需要人工维护的工作。同时又以传统的微服务的理念协作,保留了微服务团队敏捷协作的特点。最大程度匹配现代的互联网开发模式。
  它,会是BFF的破局者吗?

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。

  • 相关阅读