好未来数据中台 Node.js BFF实践系列文章列表:

  • 基础篇
  • 实战篇(TODO)
  • 进阶篇(TODO)

好未来数据中台的Node.js中间层从7月份开始讨论可行性,截止到9月已经支持了4个平台,其中3个平台生产环境稳定,另1个在测试阶段近期上线。

我4月份刚加入数据中台,原本的想法是半年内不做大刀阔斧的改变,优先完善团队现有的基建设施,比如组件库、charts库、工具、规范等。Node.js中间层的立项完全是一个意外。

某次中台周例会上讨论到前后端协作效率问题,我一时嘴贱提到Node.js中间层的想法,将应用平台的一些与DB无关的逻辑放到Node层让前端伙伴们负责,让后端伙伴集中精力做底层服务建设。

本来就随口一提,结果老板当真了,当场拍板:搞!我当时的表情大概是...

没办法,自己画的饼,哭着也要吃完。

咦?怎么有点往日重现的感觉?曾经在腾讯云,刚给客户吹完牛逼就想抽自己大嘴巴~

Node.js 的定位

数据中台 Node.js 中间层的定位类似一层 API Gateway,承载接口代理、聚合以及与DB 无关的部分业务逻辑

在现阶段数据中台的服务体系中有两类服务:常规 Java 后端和 T-Service 。后者是数据中台将 OneService 方法论落地的统一数据服务,即服务于各个前台事业部,也为数据中台内部的各个应用平台提供数据服务。

使用 T-Service 的协作流程简单描述就是数仓伙伴建表后将数据源接入 T-Service,然后 Java 后端伙伴配置取数 SQL,最后前端从统一的 query 接口查数展示

T-Service 不直接对接前端,旧架构体系下需要在前端与 T-Service 之间搭建一层 Java 服务,说白了就是一堆 Controller,从 T-Service 取数后做一些很简单的二次加工给到前端。Node.js 中间层的目标之一就是将这些复用性很差的 Controller 拿过来,好处有两点

  1. 旧架构体系下完成一个数据查询功能需要牵涉数仓、后端和前端三方,新架构下只需要前端和数仓;

    前提是前端伙伴需要掌握 SQL,前期由后端同事辅助,过渡后需要前端伙伴自己写 SQL。

  2. 基于第一条, Java 后端伙伴的生产力被解放,集中精力做底层建设或通用性更强的接口。

除了以上两条以外还有另一个隐藏优势,前端的能力边界扩宽后技术视野也会更宽阔,能够从纵向角度上全面思考业务

具体到职责分配上,Node.js 作为直接与客户端交互的服务层,登录认证是最基本的功能之一,Java 后端服务只需要关注 Node.js 传递的用户 ID 即可。

数据中台有一个统一的用户管理中心提供登录/登出服务,客户端登录后会接收管理中心下发的 JWT,后续业务接口的请求会验证 JWT 的有效性。接入 Node.js 中间层以后,JWT 的验证逻辑就上浮到了 Node 层

由于 Node 层只需要验证(解密) JWT,不需要 JWT 加密算子,所以非对称加密是相对较优的方案,比如 RS256。用户中心提供一个获取公钥的 API,Node.js 拿到公钥后进行解密即可。

技术选型

技术选型方面并没有纠结太久,其实用什么框架都行,虽然每个框架都有各自的优缺点,但由于 Node.js 中间层的逻辑不会很重,复杂度不高,框架层面的问题几乎不会成为瓶颈。所以一句话总结技术选型的核心出发点就是:用着舒服就行了。

最终用的 NestJS v7,当然也并不是完全没有量化的因素。首先跟 express 和 koa 相比,NestJS 的模块抽象层次更高,将中间件进一步抽象为 guards 、 filter 、 interceptor 等等,能够满足大多数场景,几乎不需要感知中间件这个概念。虽然有一定的理解门槛,但熟悉之后写代码能够将各模块的功能划分更加清晰容易维护。其次,NestJS 与 Express 完全兼容,生态足够丰富。最后,完美支持 TypeScript,搭配 DI 、IoC 等机制,代码的结构和模块体系非常清晰。

之所以选了 v7 而没有用最新的 v8 版本,原因之一是 NestJS 的 v8 版本依赖 RxJS v7。RxJS v7 废弃了很多 v6 版本的操作符,用惯了 v6 一时之间切换过来很不习惯。

不过 NestJS 也并不是没有缺点。举个例子,Node.js 通常使用 async hooks 进行异步资源跟踪,比如日志。NestJS 的依赖注入机制提供了一种 Request 作用域的 Provider,表面上看完全可以解决请求上下文的资源共享,但实际上并不好用,因为 NestJS 对 Request 作用域的 Provider 有一条额外的限制:依赖 Request 作用域 Provider 的 Provider 也必须是 Request 作用域的(很拗口吧)。由于日志模块是通用模块,被很多模块依赖,所以在这条限制下,从 app scope 到 module scope,几乎每个 Provider 都会被牵涉。所以最后还是用了常规方案:cls-hooked。

也有可能是我学艺不精,还没掌握 NestJS 的精髓,欢迎指正。

服务治理

Node.js 服务部署在公司的未来云 k8s,上层没有接网关,所以 https 的支持是在由 ingress 这一层提供,目前的方案比较原始,没有自动化工具,需要手动修改 ingress 配置。除此之外,在服务治理方面需要重点关注两个方面:守护进程日志管理

守护进程

在 k8s 普及之前,Node.js 的进程守护需要借助一些第三方工具,比较知名的比如 forever 和 pm2。使用这些工具会占用一些额外的机器资源(cpu、内存),借助 k8s 探针完全可以取代它们。

未来云提供了两种存活检查的探针:Http 和 TCP。

Http 探针本质上是向某个接口发起 Get 请求,响应成功状态码代表服务健康,否则判定为坏死重启 pod。对于 Node.js 来说就相当于一次请求,所以需要 Node.js 提供一个专用的接口比如/health,需要额外工作,并且这个接口不应该记录日志。

TCP 探针本质上是尝试与容器建立 socket 连接,成功代表服务存活,否则判定为坏死重启 pod,对 Node.js 服务本身没有依赖和影响。

Http 探针由于发起的是一个真实请求,所以通用性更强,但是需要额外的工作。

如果 Node.js 上层有额外的一层反向代理比如Nginx,那么一定不要使用 TCP 探针。因为 Nginx 本身就能够建立 TCP 连接,所以如果用 TCP 探针的话检测结果永远是健康的。

数据中台的 Node.js 服务每个 pod 都是单核,没有使用反向代理的必要性,所以最终使用 TCP 探针做存活检测。

日志管理

与 Java 服务的日志一样,Node.js 服务的日志也是 ELK 一把梭。需要注意两点:

  • 与 Java 后端的日志串联

    Node.js 与 Java 后端约定一个日志串联的规范,Node.js 向 Java 发起的请求头中携带一个额外字段 x-trace-id,值为 Node.js 生成的 requestId。

  • 过期日志文件及时清理

    Node.js 的日志文件以天为单位分割文件,每天都会创建几个单独的文件(errors/warnsing/infos/expcetions),如果不及时清理的话会把磁盘打爆进而造成服务重启,所以需要添加一个定时任务清理过期文件。

总结

现阶段的 Node.js 中间层刚起步,还比较轻量,以后还会遇到更多挑战。本文简单记录了一些搭建过程中的经验,有正面的可能也有反面的,欢迎指导。

下一篇会写一下目前接入的几个项目中 Node.js 中间层扮演的角色和具体做的事情,敬请期待。

好未来数据中台 Node.js BFF实践(一):基础篇的更多相关文章

  1. 深入理解node.js异步编程:基础篇

    ###[本文是基础内容,大神请绕道,才疏学浅,难免纰漏,请各位轻喷] ##1. 概述 目前开源社区最火热的技术当属Node.js莫属了,作为使用Javascript为主要开发语言的服务器端编程技术和平 ...

  2. Node.js & BFF & FaaS

    Node.js & BFF & FaaS server https://github.com/PacktPublishing/Node.js-Web-Development-Fourt ...

  3. Node.js最新技术栈之Promise篇

    前言 大家好,我是桑世龙,github和cnodejs上的i5ting,目前在天津创业,公司目前使用技术主要是nodejs,算所谓的MEAN(mongodb + express + angular + ...

  4. 团队中的 Node.js 具体实践

    前天,我们公司前端团队的几个人一起去大搜车参加了芋头所组织的「搜车 Node Party」.这是我第一次参加与 Node.js 相关的线下聚会,如果不算「杭JS」的话. 聚会现场 这次聚会的主题全部是 ...

  5. 【Nodejs】392- 基于阿里云的 Node.js 稳定性实践

    前言 如果你看过 2018 Node.js 的用户报告,你会发现 Node.js 的使用有了进一步的增长,同时也出现了一些新的趋势. Node.js 的开发者更多的开始使用容器并积极的拥抱 Serve ...

  6. 解决Postman发送post数据但是Node.js中req.body接收不到数据的问题[已解决]

    之前编写后台接口,测试数据都是使用的Postman,相当的方便,之前也一直使用get方法,编写Node.js一直没有问题,但是由于要编写一个注册/登陆的功能,所以发送的post数据,后台的逻辑已经编写 ...

  7. Node.js之路【第一篇】初识Node.js

    什么是Node.js 1.Node.js就是运行在服务端的JavaScrip. 2.Node.js是一个基于Chrome JavaScrip运行时简历的一个平台. 3.Node.js是一个非阻塞I/O ...

  8. Node.js入门教程 第五篇 (Express框架)

    Express框架 Express是适用于Node.js web的框架,提供了大量实用功能,例如路由功能及http功能. Express 框架核心特性: 可以设置中间件来响应 HTTP 请求. 定义了 ...

  9. Node.js 自学之旅(初稿篇)

    学习基础,JQuery 原生JS有一定基础,有自己一定技术认知(ps:原型链依然迷糊中.闭包6不起来!哎!) 当然最好有语言基础,C#,java,PHP等等.. 最初学习这个东西的原因很简单,在园子里 ...

随机推荐

  1. Linux初探之如何查看帮助文档自学命令

    linux命令种类繁多,参数各异,要每个都记住除非是过目不忘的神人,否则你只能记住常用的那几个,等到 要用时还是得靠--help,man,info这些命令去读文档,可是这些文档看起来也不那么直观,所以 ...

  2. Qt 中的属性系统(Property System)

    21 人赞同了该文章 本节内容主要讲解我对 Qt 属性系统的理解.官方文档参考 The Property System. 如何理解"属性系统"这个概念? 一般我们说一个类有什么属性 ...

  3. 搭建zabbix监控系统详解

    搭建zabbix监控系统详解 文:warren   博文大纲:一.前言 二.zabbix监控架构三.搭建Zabbix监控服务器四.搭建过程中遇到有些服务无法正常启动的解决办法 一.前言 : 要想实时的 ...

  4. 工作效率:通过pycharm的模板代码减少重复工作

    摘要 在常见的业务开发场景下,经常要开发大量重复的代码,这里代码耗时但又必要,就像我们写分析报告一样,每次都要为固定的格式耗费精力.我们可以更加日常开发经验总结出一些常用的模板代码来帮助我们实现一秒五 ...

  5. RabbitMq四种模式介绍和授权

    rabbitmqctl change_password admin admin123 修改admin密码 界面管理和授权操作 1新增用户 rabbitmqctl add_user admin amin ...

  6. 二.Go微服务--令牌桶

    1. 令牌桶 1.1 原理 我们以 r/s 的速度向桶内放置令牌,桶的容量为 b , 如果桶满了令牌将会丢弃 当请求到达时,我们向桶内获取令牌,如果令牌足够,我们就通过转发请求 如果桶内的令牌数量不够 ...

  7. Ajax重构

    Ajax重构简介 Ajax的实现主要依赖于XMLHttpRequest对象,但是在调用其进行异步数据传输时,由于XMLHttpRequest对象的实例在处理事件完成后就会被销毁,所以如果不对该对象进行 ...

  8. rtl8188eu 驱动移植

    测试平台 宿主机平台:Ubuntu 16.04.6 目标机:iMX6ULL 目标机内核:Linux 4.1.15 rtl8188eu 驱动移植 在网上下载Linux版的驱动源码: wifi驱动的实现有 ...

  9. 腾讯与Intel就云游戏的探讨

    今天去参加了在腾讯北京总部的腾讯音视频技术 HUB 技术巡回大会,对其中的云游戏应用的探讨格外感兴趣.正巧最近元宇宙概念很火,这篇文章就大会中对云游戏的探讨进行总结和汇报. 讲述一下来自Intel的工 ...

  10. adb 常用命令大全(7)- 其他实用功能

    屏幕截图 adb exec-out screencap -p > sc.pn 截图保存到电脑执行该命令的目录下 如果指定文件名以 .png 结尾时可以省略 -p 参数 注意 如果 adb 版本较 ...