1.概述
当采用分布式架构后,一次请求会在多个服务之间流转,组成单次调用链的服务往往都分散在不同的服务器上。这就会带来一个问题:
故障难以溯源。
发起请求,然后请求报错,到底是调用链中哪一环出了问题?很难以定位。这时候就需要用到链路追踪技术了。所谓的链路追踪技术,也就是想办法让分布式系统中的单次请求的链路调用成为可被追踪的,便于在出现故障的时候进行快速的定位溯源。
目前有两套实现思路:
- 基于日志来实现,常用到的有Sleuth、zipkin
- 基于agent来实现,常用到的有skywaiking
本文着重于介绍链路追踪的概念和大概体系,sleuth、zipkin、skywalking具体的详细教程会在后续有文章推出进行具体介绍。
2.基于日志的实现
2.1.实现思想
当分布式系统中的一次请求报错时,如何定位错误?大家的第一反应可能都是去挨着看链路上各个服务的日志。这是肯定的,因为只能从这里下手。查这些日志的过程中有个很麻烦的问题——如何将不同服务间的日志对起来?一次调用在调用链的上一个服务留下了一条日志,我怎么知道这条日志对应着链路的下一个节点的哪条日志喃?所以要给每一次请求一个编号。基于这个思想,于是有了标准日志格式规范——OpenTracing。
OpenTracing规定了标准的日志格式如下:
服务ID,服务名称。
trace ID,每一次请求,调用链上的各个服务trace ID是相同的,也就是每一次请求的编号。
span ID,各个服务不同,用来区分链路上的不同节点。
导出标识,
2.2.sleuth
依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> <version>3.1.8</version> </dependency>
这里我们搭建了一个简单的微服务集群,然后在APP、AuthenticationCenter、Bis中均引入sleuth:
AuthenticationCenter,鉴权中心,用来登录获取token,校验token是否合法。
APP,服务提供方。
Bis,Bis调用AuthenticationCenter登录,然后校验token是否合法,合法的话,再去调用APP中提供的服务:
最后去访问bis,会看到:
bis的日志:
AuthenticationCenter的日志:
可以看到Bis中一个方法中发出的所有请求在下游的trace ID全是一致的,只是span ID不同。
2.2.可视化
光有了日志,进行问题排查还是要一条条的翻,还是很繁琐。所以配套出现了可视化工具,由推特开发的——zipkin。其能对标准opentracing格式的日志进行收集和展示:
效果图:
3.基于agent的实现
skywalking是基于java agent来实现的,java agent是jkd 1.5引入的新特性,允许在main方法之前执行premain方法,来完成一些准备动作。关于 java gent,其在很多地方都有使用到,博主后续会有文章专门体系化的介绍java agent,并用java agent+字节码增强的方式来对类进行增强和监控,此处不展开。
sky walking的使用很简单,用-agent来启动即可:
java -javaagent:skywalking-agent.jar -Dskywalking.agent.service_name=a-service -Dskywalking.collector.backend_service=192.168.31.10:11800 -Dskywalking.logging.file_name=a-service-api.log -jar a-service.jar
-Dskywalking.agent.service_name,应用的名称。
-Dskywalking.logging.file_name,数据需要上传到哪里。
skywalking拥有更加的强大和细粒度的图形监控界面。