但行好事,莫问前程。互联网的前程如何网络上各种大神从十万八千个纬度已经分析过了,但是作为技术人员,我们需要的是练好内功,厚积薄发。
一、为什么要用链路跟踪
微服务大行其道的今天,如果做的是一个单体应用,甚至三个以内的服务,对于问题的排查上,使用原始的登录服务器,一个一个日志文件对比当然可行,并且一般结合用户的资金情况,大概率是要使用这种方案的。
然后当有了五个、十个、五十个服务,每个服务有10个节点的集群时候,怎么破?一台一台去查?当然不现实。这时候就需要一个分布式日志系统来帮忙收集、清洗、分析日志,并提供良好的查询方式。
日志可以查询了,那么所有的都集中到一起,微服务又是网格状调用关系,怎么知道哪个服务的上下游关系呢?知道了上下游之后又怎么对应到某一次请求上呢?顾名思义:链路跟踪解决某一次请求从头到尾(经历N个微服务调用)的整个链路状况,包括各服务上时间消耗、调用顺序等。
二、方案选择
基于以上需求,日志管理系统当前有多种解决方案:阿里系、腾讯系。当然对于更多的应该是开源系,开源环境中当前最流行的莫过于ELK架构。但是对于这个系列文章,只针对日志系统中链路跟踪这一个小的点进行讨论。网上有多种方案,zipkin+sleuth、skywalking、CAT、Pinpoint等,各有优缺点,大家可以参考下图自行比较选择。
由于我使用springboot+spring cloud,因此决定走全家桶的模式,选择zipkin+sleuth,理论上应该会支持的更好,然鹅······
现实很骨感,因为我的RPC框架选择了dubbo,而阿里早已将dubbo交给apache,包路径已从com.alibaba.dubbo 2.6.6 升级为org.apache.dubbo 2.7.12,而sleuth的进展比较缓慢,如今仍不支持dubbo2.7+,因此暂时舍弃sleuth,只集成zipkin来进行手动跟踪。
三、原理
通过拦截器生成(或放入)traceId,spanId,parentId,其中traceId作为整个请求过程的跟踪依据,贯穿整个请求过程;spanId为某个服务唯一,作为下游服务的parentId,用于构建上下游调用关系。
四、预期效果
构建web应用A,dubbo服务B,dubbo服务C。
A作为请求入口,调用服务B,服务B作为消费者,调用服务C。
希望可以通过traceId,spanId,parentId来分析整个调用过程。
希望得到如下结构,便可根据traceId=1获取整个请求过程由A、B、C组成,且调用关系为A-->B-->C:
A: traceId = 1,spanId = 1,parentId='';
B: traceId = 1,spanId = 2, parentId = 1;
C: traceId = 1,spanId = 3, parentId = 2;