一、为什么需要链路追踪
1.1 问题
随着微服务架构的演进,单体应用按照服务维度进行拆分,组织架构也随之演进以横向、纵向维度拆分
- 一个业务请求的执行轨迹,也从单体应用时期一个应用实例内一个接口,变成多个服务实例的多个接口
- 对应到组织架构,可能跨越多个BU、多个Owner
在日常工作中,一旦遇到问题,跨部门沟通、联调、排障的开销是不可控的,通常一个本身很简单的问题因为缺少直观有效的线索,可能会导致一群人花费大量的时间,朝着跟问题完全不相干方向探求真相。结果是工时用掉了,问题没解决,专注技术、不擅长博弈谈判的同学还可能被安利担责;若造成了劣币驱逐良币,可就损害了公司、老板的利益。
之前笔者有一些偏见认为只有当分布式应用的规模达到一定量级的情况下,才需要全链路追踪。最近跟一个朋友聊天时被上了一课,“有链路追踪总是要好于没有的,有就提高了可观测性,没有的话几乎全凭盲猜;遇到的问题是都能猜出来的嘛?谁又知道要猜多久嘞?猜问题不领薪水嘛?到底是在猜问题还是在带薪摸鱼呢? ”。好家伙,这一番话使我不得不坚信链路追踪降本增效的功效没用之前你是想不到的,谁用谁才知道。
1.2 诉求
系统上下游相关的如运营、客服、技术支持、开发者、管理者,都特别需要异常出现时,拥有一个轻便、高效的工具,帮助直击问题的命门。
多数人都会希望缩减沟通协作方面的精力和时间耗费,精准判断故障影响范围,做出快速响应、及时止损。另外在日常的架构调整、回归时快速的梳理服务依赖并判断依赖的合理性,在性能检测、评估场景下,分析链路性能并实施容量规划。
那到底能否高效排障呢?笔者这里有个案例不妨一看(若有雷同实属巧合):
在后续的文章《通过SkyWalking洞察Seata分布式事务处理的每个细节》里也能让大家感受到链路追踪的魅力
二、链路追踪的产品与选型
2.1 溯源
网络资料显示,谷歌的 Dapper系统,算是链路追踪领域的始祖,其论文中给出了链路追踪的设计雏形,以时序和关联依赖两个维度抽象出系统的执行轨迹,展示出系统间、组件间的依赖关系和执行耗时。
受谷歌公开Dapper论文中提出的概念和理念的影响,一些优秀的企业、个人先后做出不少非常nice的产品,有些还在社区开源共建,对这些产品进行评比的文章很多,在笔者的实践中,这几个系统是这么考量的。
- Uber的Jaeger: go语言,不在此的语言栈的慎重
- Twitter的Zipkin:侵入式的,强耦合项目,推动升级麻烦
- 韩国的Pinpoint:Hbase存储,对按多样化的业务属性查询不友好
- 中国的SkyWalking:主打非侵入式,apache顶级项目
2.2 SkyWalking的优势
2.2.1 能力强
- 提供多种语言的自动探针,支持 Java、JS、C#、GO 等多种语言
- 观测能力覆盖了基础设施如K8S、Istio、envoy;提供多个开源项目、组件的插件,如 Java 栈的 Spring、 HttpClient、Dubbo、RocketMQ、MySQL 等
- 功能丰富,可视化效果优秀
采用先进的流拓扑分析(STAM)
- STAM:针对大型分布式应用系统的拓扑自动检测方法,文档地址:https://wu-sheng.github.io/STAM/README-cn
- 架构灵活,方便扩展
2.2.2 生态好
- 社区活跃,迭代迅速
- 大厂实践,系统健壮
2.2.3 架构轻便
通过常规的Kafka、ES、Prometheus、ZK等中间件组合即可搭建系统,容器\非容器环境都可稳定工作。
三、SkyWalking 中 Trace的采集与上报
3.1 采集
目前编者已知的构建Trace的方法有5种:
1)通过SkyWalking Agent 自动构建,用户无感知
- 已提供几十款插件,官网查看详情【Java Agent 已支持的插件清单】
- 关于SkyWalking Agent体系化的介绍可查看《当月亮守护地球 | SkyWalking Agent守护你的应用...有它相伴才安逸》,此篇中介绍了可观测性的需求、多种采集机制的对比、Java Agent机制的优势、SkyWalking Agent的设计原理以及优化措施。
2)开发人员在方法上添加 @Trace 注解构建 Trace
- 添加pom依赖
<dependency> <groupId>org.apache.skywalking</groupId> <artifactId>apm-toolkit-trace</artifactId> <version>${skywalking.version}</version> </dependency> 复制代码
@Trace
注解标注在方法上,SkyWalking会给该方法生成一个对应的LocalSpan
,记录此方法的耗时信息,也可通过@Tags
注解添加标签信息,可记录入参和返回值信息。
@Trace(operationName = "myTrace") @Tags({@Tag(key = "input", value = "arg[0]"), @Tag(key = "output", value = "returnedObj")}) private String trace(String plaintext) { return "@Trace"; } 复制代码
- 《通过注解方式构建 SkyWalking 的Trace》(写作中)
3)配置文件方式指定待追踪的类方法,效果同@Trace
- 方法 2 介绍了了一种轻量级的侵入式实现,对指定的方法配置注解。但在某些场景下,可能不方便修改项目源码,这个时候可选择非侵入式方式来实现方法级的链路追踪。通过
apm-customize-enhance-plugin
插件,其工作机制是按既定格式通过配置的方式自定义增强程序中的什么类的什么方法,指定什么OprationName,如何构建Tag;能力还是构建类里方法的 trace 信息,详情可查看官网文档。 - 《通过配置文件方式构建SkyWalking 的Trace》(写作中)
4)开发人员使用显式的编程 API 来构建 Trace
5)其他产品的 agent采集后,导入到SkyWalking 中
- 比如导入zipkin采集的数据,但笔者没有这方面的实践,所以需要读者朋友自己查阅资料,做进一步的了解。
3.2 数据上报
目前编者已知的上报Trace的通道有3种:
1)通过HTTP
- 如H5中JS agent采集的数据是通过HTTP方式上报。
2)通过GRPC
- SkyWalking Agent(JAVA)默认采用GRPC方式上报数据,GRPC + Protocol Buffer,GRPC采用了Http2协议其多路复用和二进制分帧的优势大大改进传输性能,实现低延迟和高吞吐量;但当数据量特别大的情况下,可能会遇到性能瓶颈(笔者没有 GRPC 通道方面的实践,所以需要读者朋友自己查阅资料,做进一步的了解)。
- 通过MQ
- 对于数据量很大的情况下,MQ具有很好的削谷填峰的功效,目前已支持的MQ类型有Kafka 和 RocketMQ。笔者使用的是Kafka。
- 《SkyWalking 的数据上报机制》(写作中)
四、总结与下篇预告
本篇介绍了为什么需要链路追踪系统、链路追踪系统的产品有哪些,为什么选择Skywalking,SkyWalking中Trace的采集与上报能力。 下一篇内容大纲:
- 介绍SkyWalking的Trace
- 4.1 trace组件介绍
- 4.2 Trace组件的设计介绍
- 介绍Trace跨进程传播
- Trace数据模型的设计
- 跨进程传播头部协议的设计
五、最后说一句(请关注,莫错过)
对skywalking架构设计、性能调优感兴趣可以查看作者的文章:
如果这篇文章对您有帮助,或者有所启发的话,欢迎关注笔者的微信公众号【 架构染色 】进行交流和学习。您的支持是我坚持写作最大的动力。