中台背景下如何用Node做BFF层

标签: 中台 背景 node | 发表时间:2020-12-20 08:21 | 作者:悟空不打白骨精
出处:https://juejin.im/frontend

中台的概念在最近几年很火,并且也是大势所趋。服务器端改造成中台,避免不了使用微服务。服务器端微服务化之后,和我们传统意义上的前后端协同开发是有区别的,我们有幸在公司中台改造中,也对前端开发模式及框架进行了改造。

服务器端微服务化

常见的服务器端语言有java、php、c#、python、golang、nodejs。每种语言实现微服务可能需要选择不同的微服务RPC框架,常用的RPC框架有:

  1. Dubbo,仅支持Java

  2. Motan,仅支持C++

  3. Tars,仅支持Java

  4. Spring Cloud,仅支持Java

  5. gRPC,支持多种语言

  6. Thrift,支持多种语言

当时公司的服务端语言主要使用Java,但是不同的部门语言的使用情况不同,可能考虑对于多种跨平台语言的支持,公司的RPC框架使用的是Thrift。

微服务化前开发模式

服务器端微服务化之前,前后端开发模式很简单,服务器端提供接口,前端直接调用。Java API这层就相当于BFF(Back-end For Front-end),严格来说任何语言都能做BFF层。

这种模式,前端只要调用服务器端API就可以,服务器端的逻辑处理及相互调用关系,前端不用关心,前端需要什么样的接口就让服务器端提供,这也是很多公司的开发模式。

微服务化后开发模式

服务器端微服务化后,会选择不同的RPC框架,就我们公司而言,我们选择了Thrift框架,此时微服务给外界提供的是RPC接口,而前端不能直接调用RPC接口,只能让Java开发人员提供HTTP接口,这样服务器端既要写微服务层,又要实现BFF层,工作量不言而喻,并且对于前后端人员的协同开发复杂化,我们看看微服务化后的开发模式:

Node作为BFF层

如果用Java实现微服务和BFF,Java开发人员要根据前端的需求来不断更改API逻辑,我们有没有一种方式,让Java开发人员只关注微服务层呢,那就是前端实现BFF层。不言而喻,前端能很好的实现BFF,那就是Nodejs的特长,如果前端实现BFF层,后端人员只需要关注微服务的逻辑,之后前端需要怎么组装这些接口,由Nodejs来实现,更改后的开发模式:

可能没使用过Node开发的同学会问,Nodejs可以调用RPC么?答案是肯定的,gRPC和Thrift都

提供了多语言支持。

Node如何调用RPC

传统开发模式中,即使有的公司使用了Node作为中间层,但是Node只是起到了代理的作用,前端请求Node提供的接口,Node甚至都没做任何逻辑处理,直接通过HTTP client或者CURL方式透传给Java层:

这种方式,Node只是一个Proxy,在项目开发中毫无用处,甚至还增加了系统维护成本。我们看看Node如何调用RPC呢,以Thrift为例,看看Thrift定义:

Thrift 是一种轻量级的跨语言 RPC 通信方案,支持多达 25 种编程语言。为了支持多种语言,跟 gRPC 一样,Thrift 也有一套自己的接口定义语言 IDL,可以通过代码生成器,生成各种编程语言的 Client 端和 Server 端的 SDK 代码,这样就保证了不同语言之间可以相互通信

所谓IDL,就是接口定义语言Interface Definition Language,Thrift官网提供了针对各种语言的IDL生产方式,都是命令行的,Nodejs也不例外。

Node如何调用Thrift RPC

  • 服务器端通过工具把接口定义生产**.thrift文件
  • 前端拿到**.thrift文件,通过工具生产Node识别的IDL文件

通过命令行工具生产Node使用的IDL文件

   thrift -r --gen js:node tutorial.thrift
复制代码

PS:Node直接调用RPC确实很麻烦,不同的微服务器接口要生成一份,导致Node会引入很多Thrift IDL文件。我们看看通过命令行工具生成IDL之后,Node怎么调用一个RPC接口:

   const Calculator = require('./gen-nodejs/Calculator');
const ttypes = require('./gen-nodejs/tutorial_types');
const assert = require('assert');

const transport = thrift.TBufferedTransport;
const protocol = thrift.TBinaryProtocol;

const connection = thrift.createConnection("localhost", 9090, {
  transport : transport,
  protocol : protocol
});

connection.on('error', function(err) {
  assert(false, err);
});

// Create a Calculator client with the connection
const client = thrift.createClient(Calculator, connection);


client.ping(function(err, response) {
  console.log('ping()');
});


client.add(1,1, function(err, response) {
  console.log("1+1=" + response);
});


work = new ttypes.Work();
work.op = ttypes.Operation.DIVIDE;
work.num1 = 1;
work.num2 = 0;

client.calculate(1, work, function(err, message) {
  if (err) {
    console.log("InvalidOperation " + err);
  } else {
    console.log('Whoa? You know how to divide by zero?');
  }
});
复制代码

可以看出,通过thrift调用一个rpc接口,不管是接口定义还是传参方式,都比直接调用http借口复杂,这也是使Node作为BFF层的一个难点。

Node BFF不止提供API

上面我们只是以提供api为例,讲解了Node如何调用微服务RPC接口,但是实际项目中Node BFF可以提供更多的服务,包括路由、网关、渲染、SSR等,而我们在真实的项目中也是这样改造的。

我们在项目中使用的BFF模型:

BFF给前端提供的能力:

  • 插件
  • 中间件
  • 路由
  • 渲染

其中Node框架可以任意选择,包括Express、Koa、Eggjs、Nestjs等,我们选择了Koa,然后基于Koa做了上层封装。

插件

提供了多种内置插件,包括logger,http client,rpc client等,也可以通过配置加载第三方插件

中间件

Gatway实现方式之一,我们通过中间件实现了sso,限流,熔断等

路由

通过路由,给不同Appcation提供了不同形式的API,不管是H5,PC,小程序还是Open Api

渲染

这层可以直接渲染Client端构建生成的index,也可以实现SSR

总结

在我们的实际项目中,可能没有直接读写DB,但是在某些内部项目中,可以通过Node读写DB,而不需要服务器端人员介入。而且Node接入缓存中间件Redis、Memcache等也是可以的,甚至也能使用消息中间件MQ。如果想要BFF层变得更灵活,易于维护,我感觉使用GraphQL作为网关层更优。

相关 [中台 背景 node] 推荐:

中台背景下如何用Node做BFF层

- - 掘金前端
中台的概念在最近几年很火,并且也是大势所趋. 服务器端改造成中台,避免不了使用微服务. 服务器端微服务化之后,和我们传统意义上的前后端协同开发是有区别的,我们有幸在公司中台改造中,也对前端开发模式及框架进行了改造. 常见的服务器端语言有java、php、c#、python、golang、nodejs.

什么是Node?

- We_Get - 博客园新闻频道
译者按:前不久Oreilly出了一本小册子“What is Node?”,扼要的讲解了Node的身世和所适用的场景,作者文笔轻松流畅、内容充实,是非常难得的学习资料.   译文全文:http://jayli.github.com/whatisnode/index.html.   作者:Brett McLaughlin ,原文:What is Node?.

Node入门

- - CSDN博客编程语言推荐文章
作者:  Manuel Kiessling. 翻译:  goddyzhao &  GrayZhang &  MondayChen. 本书致力于教会你如何用Node.js来开发应用,过程中会传授你所有所需的“高级”JavaScript知识. 本书绝不是一本“Hello World”的教程. 你正在阅读的已经是本书的最终版.

浅析Hadoop Secondary NameNode,CheckPoint Node,Backup Node

- - CSDN博客云计算推荐文章
Hadoop SecondaryNameNode并不是Hadoop 第二个NameNode,它不提供NameNode服务,而仅仅是NameNode的一个工具. 这个工具帮助NameNode管理Metadata数据. NameNode的HDFS文件信息(即Metadata)记录在内存中,client的文件写操作直接修改内存中的Metadata,同时也会记录到硬盘的Edits文件,这是一个Log文件.

[译]什么是Node?

- blacktulip - Taobao UED Team
译者按:前不久Oreilly出了一本小册子“What is Node?”,扼要的讲解了Node的身世和所适用的场景,作者文笔轻松流畅、内容充实,是非常难得的学习资料. 译文全文:http://jayli.github.com/whatisnode/index.html. 作者:Brett McLaughlin ,原文:What is Node?.

用node作桌面开发

- InterMa - CNode社区
node的定位是,server-side javascript. 但程序员最爱做的事,就是把一个东西用在不该用的地方. 那么,可以把node用在桌面开发上吗. 把Javascript用在桌面开发上,早有先例,比如GTK+的gjs,还有Qt的QML(顺带一提,QML代表着桌面开发的另一个方向,a promising way),GNOME3中,也用javascript作为桌面插件的开发语言.

node js 断点调试

- - Web前端 - ITeye博客
大部分基于 Node.js 的应用都是运行在浏览器中的,. 例如强大的调试工具 node-inspector. node-inspector 是一个完全基于 Node.js 的开源在线调试工具,提供了强大的调试功能和友好. 的用户界面,它的使用方法十分简便. 首先,使用 npm install -g node-inspector 命令安装 node-inspector,然后在终.

Vercel 部署 Node 服务

- - 掘金 前端
之前在写 面试常客:HTTP 缓存时,曾经就强缓存和协商缓存写过两个demo,但缓存要在服务端做,只能贴上代码,不能在网页上感受(虽然我贴了gif). 笔者的所有 demo 例子都放在 github page 上,其特点是不需要服务器即可部署静态资源,但它不具备部署服务端应用能力. 最近笔者在了解 CI/CD 方面的知识点,想起了 Vercel,就想着能否将服务端应用架在 vercel 上呢.

無痛安裝 NodeJS 和 Node Framework Express

- Hming - 小惡魔 - 電腦技術 - 工作筆記 - AppleBOY
直接到官網下載 Stable 的版本吧,目前是 node-v0.4.10.tar.gz,也可以先看看 API Document. 安裝 Ububtu 相關套件. 下面會使用最原始的編譯方式,所以必須安裝 g++ 套件,否則下 ./configure 的時候,會吐出來沒有安裝過的套件. 兩種方法:1.用 apt-get install nodejs 2.