转-BFF调研-1

转自:  https://blog.youkuaiyun.com/duola8789/article/details/89332064 

 

前端开发中存在的难问题

  1. 多端应用,不同类型客户端对数据、API有个性化的需求
  2. 服务聚合,单一后端为多个前端团队提供接口,导致跨团队协作低效,资源协调困难

问题:服务端设计的接口究竟是面向UI,还是面向通用服务

BFF

解决方案: Backends For Frontends, 简称BFF。

BFF最适合的场景,为第三方提供定制API等差异化场景,每个用户体验(客户端)对应一个后端,

v2-50720e139878624f394dcf2d3de836fb_hd.jpg

BFF作为用户体验适配层,对后端接口进行组合、处理,对数据进行:裁剪、格式化、聚合、编排。

BFF理念中,最重要的一点是:服务自治,谁使用谁开发,所以一般由前端维护。

BFF实现不限制具体技术,可以自由选型:Java/Node/PHP/Python,但大部分前端团队都会选择Node.js。

BFF的演化历程

BFF和网关(API Gateway)是微服务架构中两个重要概念,可以通过下面的例子讲解BFF的出现过程

服务化架构V1

实现单块应用的解构拆分,微服务初步完成,前端用户体验层主要是传统的服务端Web应用,服务化架构如下所示:

service4.png

服务化架构V2

随着无线应用的流行,除了Web应用外,服务还需要为新的无线原生App来提供接口和数据,先采用下面的服务架构:

service5.png

这样的架构的问题是:

  1. 无线App与内部为微服务强耦合
  2. 无线App需要知道内部服务的地址等细节
  3. 无线App需要对接口数据进行大量的聚合剪裁和适配逻辑

服务化架构V2.1

为了解决这个问题,在用户体验层和内部微服务层之间引入了BFF层,将后端的微服务进行适配,想用户体验层暴露有号和统一的API,方便无线设备接入访问后端服务

service.png

这种架构解决了上面的问题:

  1. 无线App与内部为微服务解耦,两边可以独立变化
  2. 无线App只需要知道BFF的地址,并且服务接口统一,不需要关心内部复杂的微服务的地址和细节
  3. 无线App需要不再需要聚合剪裁和适配逻辑,这些步骤都在BFF完成

但是随着接入设备的增加,也会有一些问题:

  1. BFF只有一个,接入设备增加后导致要考虑匹配问题,团队之间沟通协调成本高
  2. BFF中不仅包括了各个业务线的聚合剪裁、适配和业务逻辑,还需要引入很多跨横切面逻辑,比如安全认证、日志监控、限流熔断等,这些代码混在一起,导致代码复杂度提高
  3. BFF如果出现错误,会导致所有应用都不可用

微服务架构V3

为了解决这个问题,引入API Gateway

serveice2.png

在这种架构下:

  1. BFF按团队和业务线进行解耦拆分,拆分成若干个BFF微服务,每个业务线并行开发和交付各自负责的BFF微服务
  2. 网关,一般由独立的团队负责运维,专注跨横切面的功能,包括
    • 路由,将来自无线设备的请求路由到后端的某个微服务BFF集群
    • 认证,对涉及敏感数据的API访问进行集中认证鉴权
    • 监控,对API调用进行性能监控
    • 限流熔断,网关能够进行限流熔断,保护后端服务
    • 安全防爬,收集访问日志,通过后台分析恶意行为,阻断恶意请求
  3. 网关在客户端与BFF之间又引入了一层,让两边可以独立变化

微服务架构V4

可以对V3架构进行优化,将传统的服务端Web应用模式改为前后分离架构,前端采用H5单页技术提供给用户更好体验。

同时增加了下手是哪个第三方应用开放API的能力

service3.png

拓展新的接入渠道,形成了一个完成的现代微服务架构,从外到内依次为:端用户体验层->网关层->BFF层->微服务层

具体实现

细分力度

要求把一个大后端拆分为多个小后端,有三种方式

  • 用户体验级(UI)
  • 端级
  • 团队级

一般建议按照用户体验级来拆分

对接下游服务(微服务)

(1)如何对接多个技术栈不同的下游服务

RPC协议调用

(2)如何管理、组合调用

借助RXJava、Finagle等事件机制来简化这些异步流程控制

(3)某个调用失败时,如何保障可用性

在BFF层容错,同时前端保证可接受不完整相应内容

复用问题

拆分后,多个BFF间会产生冗余代码,这是不可避免的。

可以添加API网关层,将通用的后端逻辑(授权、认证、限流)放进去

想消除冗余,又不想因为抽离可复用代码而导致BFF间紧耦合,所以就有了一种折衷的态度:容忍BFF间冗余、消除单BFF内冗余。也就是允许一定程度的BFF间冗余

蚂蚁财富的BFF实践

2016年时,汤尧对BFF在蚂蚁财富项目中的落地实践进行了介绍。

在引入BFF之前,蚂蚁财富的业务也遇到了上面提到的问题,主要是体验层API经常变化,导致开发效率低下。

于是引入了BFF,主要的目的是对数据进行:裁剪、格式化、聚合、编排。

一个理想的模型如下:

BFF-11.png

在实际落地过程中,形成了如下的架构:

BFF-1.png

他们在实战过程中,主要解决了一下几个问题:

(1)Node.js与Java通信

  • 数据:跨语言序列化协议hessian
  • 服务:Node弱类型,Java强类型,如何调用

BFF-2.png

这个调用过程一般是通过RPC协议完成的,而非通过HTTP协议。

由于我对Java没有接触,而且资料只是他当时的PPT,没有详细的讲解,没有办法理解具体是如何实现的。而且恐怕对于大多数前端开发工程师来说,与Java的通信也是BFF落地过程中一个比较严峻的挑战,而且这是在前端开发人员有比较好的Node开发能力的基础上。

(2)多App适配

在API网关层处理多个App的通用的逻辑,比如错误码管理、数据一致性、免登、业务日志等。

(3)聚合

BFF-3.png

  • 传给客户端需要的数据,简化客户端逻辑,减少网络开销
  • 避免无意义的透传
  • 敏感信息过滤

(4)接口设计准则

基础服务接口:(微服务?)

  • 细粒度
  • 通用的功能,可能会被多个BFF用到
  • 提供含各种状态的mock真实数据,易于同步开发(如何实现?)

BFF API设计

  • 合理设计接口数量,太多不易维护
  • 提供含各种状态的mock真实数据,页面不依赖server开发(如何实现?)
  • 多协议发布(如何实现?)
  • 规范数据格式

在落地BFF过程中,从技术角度来看:

  • 前端和BFF由同一人完成
  • 前端需要具备服务端技能
  • 快速的应用发布能力(docker?)

TWA的理念与实践

在2018年的SEE Conf,蚂蚁金服的不四(知乎ID:死马)对在BFF基础上发展出来的TWA(Techless Web Application)开发体系进行了介绍(视频PPT)。

传统的分层:

BFF10.png

BFF负责聚合底层业务数据,给客户端提供接口,秉承谁使用谁维护的理念,一般由前端团队维护。

v2-d245bbeae2b0245da8858bd237b344f7_r.jpg

业务实际上分为三层:前端(HTML/CSS/JS)+ BFF(Node.js接口聚合层)+ 后端服务(Java)

BFF-6.png

BFF on Chari是蚂蚁自研的,基于Egg.js的BFF框架,打通了Node到Java的RPC通信链路

Egg.js已经开源(Egg.js是以Koa作为基础框架),需要基于Egg.js去打造属于自己的BFF框架

RPC的意思是不在一个内存空间的两个应用,借助网络来实现,像调用本地的函数一样去调用远程函数

BFF不是银弹,有着自己的问题:

BFF-7.png

  • 研发成本上升:前端团队既要开发客户端,又要开发BFF,人手不够
  • 流程繁琐:BFF引入后,要同时走前端、服务端的研发流程,多端发布、互相依赖,导致流程繁琐
  • 运维经验不足:主要是前端工程师运维经验不足(给业务团队带来了很大困扰)

尽管职责划分越来越清晰,但是由于前后端发布系统不一致,前端团队仍需要在基于不同的代码仓库进行研发,走不同的发布流程

理想的开发流程:

TWA.png

蚂蚁金服推出的解决方案TWA(Techless Web Application),是一个全栈的研发框架

TWA是为了提升开发者研发体验而推出的渐进式解决方案,开发者在一个代码仓库下,基于TWA的框架,完成客户端和BFF层的研发,通过Basement研发平台提供的流程支持,不用再关注应用、构建、部署、流程等细节,可以一键将应用部署到各个运行终端,同时在研发平台上完成应用的自主运维和监控

将TWA拆解开来,分为了三个大的方向:框架、研发平台、运行时

  • 框架:提供了前后端合一的框架,通过定制化网关,抹平多个终端和接入形式的差异,让一套代码可以运行在不同的终端下(?)
  • 研发平台:Basement,提供TWA的研发迭代、自主运维和监控,精简规范了H5 APP的研发流程
  • 运行时:通过基础服务和Docker,给客户端代码和服务端代码提供稳定可靠的运行环境

TWA2.png

框架

是一个渐进式框架,可以选择部分能力使用

TWA3.png

客户端、服务端目录、依赖都是相互独立的。

复杂的终端环境,有不同的接入链路(可能通过网关走TCP长连接通信)、不同的鉴权方案。如果每个业务的BFF系统要对接到每个系统完成接入、鉴权是非常复杂的。

TWA网关2.png

解决方案是:TWA网关层 + 客户端RPC Client,

TWA网关2.png

TWA网关层统一完成所有终端的接入、鉴权,BFF不需要对接到每个终端,只需要对接到网关,让BFF接口统一

客户端的RPC Clinet是一个请求库,对接到网关,将客户端的鉴权、接入的细节隐藏,并且可以自动选择接入链路

这就可以在client目录下,像调用本地方法一样,调用server中目录下的服务

TWA-4.png

研发平台

Basement.png

Basement,一站式运维平台,基于Docker,支撑整个应用的研发流程,完成自动化的测试和部署

TWA-6.png

Node与Java的通信

与使用的微服务框架有关,可以采用HTTP的方式,也可以通过RPC调用。

蚂蚁金服的实践

  • 数据:跨语言序列化协议hessian
  • 服务:Node PRC

开源框架:

  1. sofa-bolt-node:蚂蚁通讯协议Bolt的Nodejs实现
  2. sofa-rpc-node:一个通用的Nodejs RPC模块

有赞的实践 – HTTP

可以采用服务注册中心:

youzan1.png

首先,Java应用服务启动的时候,会往服务注册中心注册服务,这里的服务注册中心可能是ETCD或者Zookeeper,然后,Node应用在启动的时候,会先从服务注册中心拉取服务列表,接着Node会跟Java服务建立一条TCP长链接,除此之外,Node还需要负责Hession协议解析以及负载均衡等。

上面的方式Node职责比较重,对Node开发的要求高,有赞在此基础上做了改进:

youzan2.png

在Node和Java之间添加了一层中间代理层Tether,Tether是用Go语言写的一个本地代理,Tether会对外暴露一个HTTP的服务,对Node来说,只需要通过HTTP方式调用本地的服务即可,其他服务化相关的服务发现、协议解析、负载均衡、长链建立维护都交由Tether来处理。这样,Node这一层就非常轻量了,Node是调用Java服务时:

const Service = require('../base/BaseService');

class GoodsService extends Service {
  /**
   * 根据商品 alias 获取商品详情
   * @param  {String} alias 商品 alias
   */
  async getGoodsDetailByAlias(alias) {
    const result = this.invoke(
      'com.youzan.ic.service.GoodsService',
      'getGoodsDetailByAlias',
      [alias]
    );
    return result;
  }
}
module.exports = GoodsService;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

这种方式的优点:

  1. 使用简单,对前端开发非常友好,只需要通过HTTP方式调用本地的Tether服务即可;
  2. 多语言接入成本低,后期如果有其他语言(Python、Ruby)也需要接入整个服务化体系,也像Node一样,它们都只需要调用本地Tether暴露的HTTP服务即可,没有额外的开发成本了。
  3. 后期更方便做协议层的优化,因为这种方式Tether其实就是一个代理,后期如果需要做协议层性能上的优化,那只需要优化Tether的性能就可以了。

总结

关于TWA

TWA是蚂蚁金服自研的,整合了BFF的一整套渐进式的前端+Node聚合层的开发体系,它不仅包括了BFF的引入,还包括了前后端代码管理、部署、运维等功能框架。

但是很遗憾的是,TWA没有开源,对于想要从0开始引入BFF,想实现TWA的功能,还有一个努力的过程。

实际上我们引入BFF,不是要完整的开发TWA,而是首先实现Chari BFF的功能。

接入BFF的好处

对于团队来说:

  • 业务支持变多
  • 沟通协作变少
  • 解决问题变快

对于个人来说:

  • 更合理分工
  • 做BFF可以拓展知识面

接入BFF的坏处:

  • 组织决定了架构的复杂度
  • 前期学习成本高,短期成为资源瓶颈

可能遇到的问题和可能的解决方法

  1. Node与Java通信 – Hessian(数据),RPC(服务)(sofa-rpc-node)/ (grpc-node
  2. 前端代码和BFF段代码管理 – Egg.js(同一个仓库,不同目录,不同依赖,分别打包、分别配置)
  3. 前端的应用发布、运维能力 – Docker
  4. 服务端的配合 – 服务:微服务(?),人员: (?)
  5. 前端能力提高 – 前端能力(JavaScript + HTML + CSS) + Node(服务端技能)+ Java(如何与Java通信)+ 运维能力(Docker)

参考

功能要求 1. 用户注册与登录 o 注册页面必须包含用户名、密码、确认密码这三个基本字段,密码强度验证规则为 至少为8个字符,并且至少包含数字和字母两种类型,在用户输入密码时实时显示 密码强度提示,例如密码仅包含数字或字母时提示 “密码强度较弱”,当同时包含数 字和字母时提示 “密码强度适中”。 o 登录页面要有登录验证功能,登录成功后跳到网站首页,在首页右上角显示欢迎 信息及默认头像(可预先设定一个通用头像),点击头像弹出下拉菜单,菜单中包 含 “个人信息查看”(仅显示用户名等基本信息)和 “退出登录” 两个选项。用户注 册和登录信息的前端验证要全面且准确,确保用户名的唯一性(可通过简单的数组 存储已注册用户名进行模拟验证,每次注册时检查新用户名是否已存在于数组中), 登录时精确验证用户名和密码的正确性,对于错误信息要给出明确、易懂的提示, 例如 “用户名不存在” 或 “密码错误”。 2. 网站首页与导航栏 o 首页布局要合理、美观大方,具备一定的视觉吸引力,注重元素排版和色彩搭配。 导航栏应包含网站的主要功能模块链接,如 “首页”、“文章列表”(个人博客网站)、 第1页 共15页 “美食展示”(美食分享网站)、“旅游目的地推荐”(旅游攻略网站)、“电影资讯”(电 影资讯网站)、“宠物商品分类”(宠物商店网站)、“联系我们” 等,导航栏样式在鼠 标悬停时要有明显的颜色变化(如变为深色或亮色)以增强交互性。 o 根据不同的网站类型,首页需展示核心内容或特色功能的简要介绍。例如,个人博 客网站展示博主最新文章的标题和摘要;美食分享网站展示热门美食图片和简介; 旅游攻略网站展示热门旅游目的地图片和特色亮点;电影资讯网站展示近期热门电 影海报和简介;宠物商店网站展示热门宠物商品图片和价格。 3. 内容展示页面(依据网站类型确定具体内容) o 文章详情页(个人博客网站):完整展示文章内容,包括文字、图片(支持插入多 张图片并实现良好排版)等,排版清晰易读。显示文章的发布日期、修改日期(若 有修改)、分类标签、阅读量、点赞数和评论数等详细信息。提供点赞和评论功能, 读者登录后可对文章点赞,发表评论(评论内容包含文字,支持简单表情),显示 评论发布时间,最新评论显示在顶部,可对评论进行回复,形成评论层级结构。 用户交互功能 o 评论与留言功能(适用于个人博客、美食分享、旅游攻略、电影资讯网站):在相 第2页 共15页 应的详情页下方设置评论区,用户登录后可发表评论,评论内容仅为文字,支持简 单的表情符号等,可预先定义几个表情。显示评论发布时间,最新评论显示在顶部, 可对评论进行点赞操作(点赞数通过数字显示,点击点赞按钮实时更新点赞数)。 管理员(或模拟管理员,通过前端设置一个固定密码的管理员入口进入管理页面) 可在后台查看和管理评论,对不当评论进行删除操作,删除后评论区实时更新。 o 联系我们页面表单提交(通用):包含姓名、邮箱、留言内容等字段,用户填写信 息后点击提交按钮,表单数据需进行前端验证,包括非空验证(确保所有字段都已 填写)、邮箱格式验证(使用正则表达式验证邮箱格式是否正确),验证通过后将数 据显示在页面上(模拟数据提交成功,可在页面上显示提交的信息),同时弹出提 示框显示 “提交成功,我们将尽快与您联系!显示与互动要求 图片轮播功能(至少在一个页面中实现,如首页或详情页) o 在首页或其他合适的页面中,设置图片轮播区域,用于展示重要图片内容,如个人 博客网站展示博主精选图片、美食分享网站展示特色美食图片、旅游攻略网站展示 热门旅游景点图片、电影资讯网站展示经典电影海报、宠物商店网站展示热门宠物 商品图片等。 o 图片轮播应具备自动切换和手动切换(点击左右箭头或图片下方的指示点)两种方 式,切换效果流畅自然,过渡动画简洁美观,可设置适当的切换时间间隔(如 3 - 5 秒)。同时,在图片轮播过程中,显示图片的标题或简要描述(可选),以增强用 户对图片内容的理解。 (三)需求分析和系统设计要求 第3页 共15页 1. 需求分析与规划 o 团队成员共同开展需求分析工作,深入调研确定所选网站类型的目标用户群体、主 要功能需求和特色亮点,确保项目目标明确、功能完整且紧密贴合用户需求。例如, 个人博客网站针对博主和读者,注重文章展示和互动;美食分享网站面向美食爱好 者,突出美食展示和分享功能等。 2. 系统设计 o 完成系统架构设计,绘制简单清晰的系统架构图(可使用流程图或框图形式),描 述各功能模块之间的关系和数据传递方式(如用户注册登录模块与文章展示模块或 商品展示模块之间的数据交互流程)。 o 精心规划页面布局和交互流程,设计每个页面的布局草图(手绘或使用简单绘图工 具绘制,展示页面元素的大致位置和排版)和用户操作流程,确保页面之间的跳 逻辑顺畅、用户操作便捷高效。例如,在宠物商店网站中,从首页到商品分类页再 到商品详情页和购物车页的跳流程要清晰明了。 (三)代码要求 o 在代码中添加必要且清晰的注释,注释应准确解释代码的功能、逻辑和关键算法, 特别是对于复杂的 JavaScript 函数和逻辑判断部分,注释要足够详细,使其他团队 成员或后续维护人员能够快速理解代码意图。 o 遵循基本的代码编写规范,如变量命名采用有意义的英文单词或缩写、函数命名具 有明确的描述性、代码缩进合理、适当添加空行提高代码可读性等,确保代码风格 统一、整洁易读。 (一)个人博客网站设计 1. 功能特色 o 除上述通用功能外,具备文章分类管理功能,博主可自定义文章分类(如生活、技 术、文化等),并在文章发布时选择分类,方便文章的分类展示和读者按兴趣浏览。 o 提供文章标签功能,博主可添加多个标签描述文章内容,读者点击标签可查看相关 标签的文章列表,增强文章的关联性和检索性。 o 实现文章归档功能,按年份和月份对文章进行归档,展示在单独的归档页面,方便 读者查看历史文章。 2. 技术重点 o 在 JavaScript 交互逻辑中,实现文章分类筛选和标签筛选功能,通过监听用户点击 事件,动态更新文章列表展示内容。 o 处理文章归档数据的展示,根据文章发布时间准确地进行分类和排序,确保归档页 面的信息准确无误。在文章编辑功能中,确保富文本编辑功能的实现,如文字格式 设置、图片插入等操作的便捷性(可选)
最新发布
12-20
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值