在Nodejs中Tracing实现的调研记录
博睿NodeJS Tracing 的大概实现方式
以Koa为例
首先,增强运行时require 函数的能力,根据require 的参数,判断是否引入了如Koa,Express等框架,然后初始化对应框架的probe(探针)
利用Koa 中间件的机制 获取中间件列表对每一个中间件进行hook(在原函数前后加上上报代码,再调用函数)
mysql, mysql2, redis, http, https 等package均为以上实现方式
so文件hook运行时内部函数
总结:开发量大,每个模块包都需要加hook,需了解包内部代码的实现,需要频繁维护,优点是无需用户埋点
opentracing-javascript
用户手动打点,可形成如下记录,可自定义强
Spans:
parent_span - 1521ms
tag 'custom':'tag value'
tag 'alpha':'1000'
child_span - 503ms
tag 'alpha':'200'
tag 'beta':'50'
jaeger-client-node
用户手动打点,引入包,然后初始化init -> 开始startSpan -> 打点span.log -> 结束span.finish
可使用initTracerFromEnv 方法从环境变量初始化,可在运行时内导入包并植入全局变量,用户即可在想打点的地方手动打点,使用方便,缺点兼容性不好
SkyWalking-nodejs
无需用户手动打点,内置部分package的自动打点,http / https, express, axios, mysql, pg, mongodb, amqplib
首先尝试加载SDK内部已经支持的框架如express,如不加载成功,则跳过,加载成功则增强其router.handle方法,将打点逻辑注入。
总结:类似全埋点,支持的模块包较少。
aws-xray-sdk
链接
配置相对复杂,需要手动指定项目使用的框架
对于express等框架也是采用hook的方式一一对应实现
工作量:运行时增加探针,对基础内置包的hook:包括net、tcp、dns等,对框架express、egg、mysql、cos等的自动识别并框架hook,运行时+基础包需要10天,第一个框架Tracing开发时间可能5天,后续框架2~3天可以开发一个
风险:需要hook每一种语言的基础内置包,每一种框架的识别需要大量工作量,后期框架升级需要更新Tracing代码。可能对用户代码产生影响,如报错的堆栈。如用户不按正常框架使用方法,对框架的Tracing可能不生效。
工作量:工作量少,完全依赖用户自己打点Tracing
风险:体验不好,对内部协议、内部云产品的Tracing支持不好,需要用户对打点的方法了解充分,并多打点,才能分析出链路耗时,找到耗时长的地方
工作量:运行时增加探针,对基础内置包的hook:包括net、tcp、dns等,需要针对云内部产品包装一层hook,用户代码层面用户手动加探针,运行时+基础包需要10天,第一个云内部产品Tracing开发时间可能5天,后续2~3天可以开发一个
风险:体验不如无埋点方案,但开发量少,可增量提供Tracing功能,