分布式追踪

206 阅读4分钟

简单介绍

分布式追踪在微服务领域非常重要,因为服务一旦多了,就涉及到性能瓶颈分析与线上问题排查、服务之间的关系梳理等等,这在单体应用的时候,非常简单,你甚至在本地就能解决,但是在一个比较大的公司内部,就需要团队与团队,部门与部门之间的合作才能解决,于是用传统这种的方案就很难解决了,在几十上百服务中一个个排查试试可真得累死人,而且找到问题的概率很低。

那么,它跟我们说的 APM 有什么关系呢?APM 的作用是监控应用性能,但是当一个应用被拆成分布式应用的时候,只是单独监控每个应用就不能达到我们想要的效果了。毕竟我们最重要的监控,就是监控一些涉及到 APP 频繁请求后端的 API 以及对应的请求链路,这些请求是用户直接能感受到的(充值购买之类的就不用提了,肯定是第一位的),当响应时长升高,或者错误率上升,是会直接影响用户体验的。这时候必然需要一个标准,来将所有的 APM 数据汇总,统一显示,方便我们监控以及查找定位问题。

再来说说业界的一些实现,Google 的 Dapper、Twitter 的 Zipkin、新美大的 MTrace 以及阿里的 Eagle Eye。简单来说,他们就是开源版本的 APM 实现,你完全能使用这些开源版本的 APM 来监控你的分布式应用。

接下来再说说 opentracing 这个项目,拿他的身份来说就不简单,CNCF 成员项目,虽然看起来成立时间也挺短的,但是潜力无限。

它的目标很简单,不是想做出一个牛逼的产品取代业界的各种实现,它只想联合开源界的所有优秀分布式组件,来做一个标准,毕竟相比于大家都各自重复造轮子,还不如大家联合起来,遵从同一个标准,把这个盘子做大。这样的话,以后你在你的中间件项目中加入 opentracing 的支持了之后,所有使用了 opentracing 相关工具的团队,就能跟你的项目无缝结合,这是不是很美好?

现在回到 APM,作为整个分布式应用中对你最重要的一部分,你就可以在你自己开发的分布式项目中,加入 opentracing 支持了。

在这里需要特别介绍下符合 opentracing 的一个实现,jaeger,主要是因为它有 Node.js 的 client:jaeger-client-node,它提供了 opentracing 的 tracer 实现,但是不能像 newrelic 那样在项目入口文件中 require 就行了,需要你手工侵入代码,非常不优雅。

目前我知道的只有一个项目有点符合要求:opentracing-auto ,只是不稳定,不建议在生产环境使用,而且当前使用的人也不够多,也没有 koa 的支持。

APM 中包含分布式追踪,但实现 Node.js 应用分布式追踪的重点还是 CLS

CLS

Node.js 官方给出了实现

他们提到的东西就是 async_hooks,只是它需要在 Node.js 8.2.1 以及之后的版本中才能使用。而在这之前其实也有一个模块 async_wrap 也提供了类似的功能,但是没有以正常的方式对外暴露,也没有文档,你必须使用 process.binding('async_wrap') 的方式。

而完整的历史在cls-hooked 这个模块的 readme有提到 (cls-hooked 是 continuation-local-storage 的一个 fork):

  1. First implementation was called AsyncListener in node v0.11 but was removed from core prior to Nodejs v0.12

  2. Second implementation called AsyncWrap, async-wrap or async_wrap was included to Nodejs v0.12.

    1. AsyncWrap is unofficial and undocumented but is currently in Nodejs versions 6 & 7
    2. cls-hooked uses AsyncWrap when run in Node < 8.
  3. Third implementation and offically Node-eps accepted AsyncHooks (async_hooks) API was included in Nodejs v8. :) The latest version of cls-hooked uses async_hooks API when run in Node >= 8.2.1

简单翻译如下:

  1. 第一次实现在 node v0.11 的时候叫做 AsyncListener,之后在 v0.12 的版本里呗移除了;

  2. 第二次实现叫做 AsyncWrap,async-wrap 或者叫 async_wrap,在 v0.12 的时候被引入了;

    1. AsyncWrap 是非官方的,也没有相应的文档记录,但是在版本 6 跟 7 中是可用的;
    2. cls-hooked 在 node 版本低于 8 的时候使用了 AsyncWrap;
  3. 第三次实现被 Node-eps(Node.js Enhancement Proposals) 接受了,叫做 AsyncHooks (async_hooks) 它的 API 被包含在了 node 8 版本中。 最新版本的 cls-hooked 使用了 async_hooks API 当版本大于等于 8.2.1;

但是这个模块对性能还是有影响的

这要看你对性能跟监控能力的权衡,相信用一小部分的性能损失来换取更全面以及清晰的监控是值得的。