撸了几天的sofa-tracer之后,我悟了!
什么是分布式链路跟踪
简而言之,在分布式系统下,用于跟踪链路而衍生出的一项技术。
应用场景如下:
应用A,B,C,D,E 以一个层级关系依赖, 当用户向 应用A
发起请求,但是返回了个异常,为了排查这个问题,我们可能要一台台服务器去排查。在分布式架构下,每个应用又部署了几十上百台服务器, 那一天下来,可能多没找到问题的触发点。
通过分布式链路跟踪,结合 如 鹰眼
等平台的 链路分析,我们可以很快定位到 问题发生机器地址。
那为什么我们可以很快速定位到哪台机器?
- TraceId 日志收集,收集异常日志,快速发现异常原因
- TraceId 埋入机器IP,快速定位异常机器
文章图片
基本概念
文章图片
文章图片
一条
trace
链路是由多个与之关联的 span
组成,一条链路整体可以看做是一张有向无环图
,各个 span
之间的边缘关系被称之为References
。- traceId: 每条链路只有唯一的
traceId
- spanId : 每个节点为一个
span
,存在层级关系
- 跨进程的透传,即如何将链路数据从一个进程传递到下游进程中
- 线程中的透传
- 当前请求跨进程调用结束之后,当前如何恢复 tracer 上下文信息
- 如何实现跨线程的透传,如在当前线程中起一个异步线程的场景
TraceId 生成规则:
服务器 IP + 产生 ID 时候的时间 + 自增序列 + 当前进程号0ad1348f1403169275002100356696
SpanId 生成规则:
root 节点为0,后续以
.
分割,不断分层延续文章图片
?
跨进程透传 TracerId
以
SOFATracer
为例 描述一下,一个 Http
请求是如何跨进程间进行传输的.SofaTracer 源码地址:
https://github.com/sofastack-guides/sofa-tracer-guides/tree/master/tracer-sample-with-springmvc
在一个 Http 请求中, 当请求经过
Filter
,SOFATracer
做的主要就是判断当前请求的header中是否存在 traceId
, spanId
文章图片
从依赖包中,我们可以看到,只有一个filter
文章图片
Header存在 Tracer 信息 将上下文信息,存放到
ThreadLocal
中文章图片
Header 不存在 Tracer 信息 创建一个新的 上下文, 生成
traceId
和 spanId
,然后存放到 ThreadLocal
中文章图片
跨线程透传 TracerId
通过深拷贝,创建一个新的上线文信息, 将 SofaTracerSpanContext 传递到子线程中
public SofaTracerSpanContext cloneInstance() {
// 重新构建一个 SofaTracerSpanContext 对象实例
// 这里会以当前父线程中的 tracerId,spanId,parentId以及采样信息 作为构建构建参数
SofaTracerSpanContext spanContext = new SofaTracerSpanContext(this.traceId, this.spanId,
this.parentId, this.isSampled);
// 系统透传数据
spanContext.addSysBaggage(this.sysBaggage);
// 业务透传数据
spanContext.addBizBaggage(this.bizBaggage);
spanContext.childContextIndex = this.childContextIndex;
return spanContext;
}
文章图片
手撸一个 DEMO MyFilter
文章图片
总结 原理看着挺简单,但是实际使用上,还要考虑很多方面的问题, 如果日志收集,日志分析,traceId 生成规则等等,感兴趣的大伙可以去看一下源码: 传送门
【撸了几天的sofa-tracer之后,我悟了!】感谢大家的阅读,希望对大家有所帮助,我是
九灵
,有需要交流的童鞋可以 加我wx,Jayce-K
,最近致力于帮助更多小伙伴加入大厂,欢迎来撩~推荐阅读
- 热闹中的孤独
- 2018-02-06第三天|2018-02-06第三天 不能再了,反思到位就差改变
- 尽力
- 你到家了吗
- 这辈子我们都不要再联系了
- 死结。
- 我从来不做坏事
- 时间老了
- 喂,你结婚我给你随了个红包
- 赢在人生六项精进二阶Day3复盘