Node.js应用全链路追踪系统

目前行业内,不考虑Serverless的情况下,主流的Nodejs架构设计主要有以下两个方案:

  1. 通用架构:只做ssr bff 不做服务器和微服务
  2. 全场景架构:包含 ssr bff 服务器微服务

image.png
在上述两种通用架构中,nodejs都会面临一个问题,那就是:
在请求链路越来越长,调用服务越来越多,其中还包含各种微服务调用的情况下,出现了以下诉求:

  • 如何在请求发生异常时快速定义问题所在
  • 如何在请求响应慢的时候快速找出慢的原因
  • 如何通过日志文件快速定位问题的根本原因。

要解决上述诉求,就需要有一种技术,将每个请求的关键信息聚合起来,并且将所有请求链路串联起来。让我们可以知道一个请求中包含了几次服务 微服务请求的调用。某次服务 微服务调用在哪个请求的上下文。
Node.js应用全链路追踪。它是Node.js在涉及到复杂服务端业务场景中,比不可少的技术保障。

全链路信息获取

业界方案

由于Node.js单线程,非阻塞I/O的涉及思想。在全链路信息获取上,到目前为止,主要有以下4种方案:

  1. dommain: node api
  2. zone.js: Angular 社区产物
  3. 显示传递 手动传递 中间件挂载
  4. Async Hooks node api

而上述 4 个方案中, domain 由于存在严重的内存泄漏,已经被废弃了;zone.js 实现方式非常暴力、API比较晦涩、最关键的缺点是 monkey patch 只能 mock api ,不能 mock language;显式传递又过于繁琐和具有侵入性;综合比较下来,效果最好的方案就是第四种方案,这种方案有如下优点:

  • node 8.x 新加的一个核心模块,Node 官方维护者也在使用,不存在内存泄漏;
  • 非常适合实现隐式的链路跟踪,入侵小,目前隐式跟踪的最优解;
  • 提供了 API 来追踪 node 中异步资源的生命周期;
  • 借助 async_hook 实现上下文的关联关系;

    Async Hooks 异步钩子