1.背景
当应用系统只有个位数的时候,完全可以靠人的记忆来理清系统之间的调用关系,也完全可以凭借人力介入来排查系统故障。但是当应用系统数量达到上百个甚至更多的时候,恐怖你就不能再靠蛮力来解决问题了,必须另辟蹊径,就需要用到今天的主角分布式链路追踪jaeger来帮你理清系统调用关系以及帮你排查系统故障。
2. 介绍
jaeger分布式链路追踪系统,用于在复杂的分布式系统中监控和排除交易故障
2.1 jaeger架构图
2.2 组件介绍
- jaeger-client:用于收集信息并通过
UDP方法上报给jaeger-agent - jaeger-agent:将信息推送给
jaeger-collector - jaeger-collector:将接收到的信息进行存储
- jaeger-query:查询存储信息
- jaeger-ui:对信息进行可视化展示
依据架构图看到的组件,我们需要在本地安装jaeger-agent、jaeger-collector、db、jaeger-ui,这些可以通过all-in-one镜像进行本地安装测试,同时也需要在项目中添加jaeger-client依赖
3. 实战
3.1 安装jaeger
3.1.1 搜索镜像
docker search jaeger
3.1.2 拉取镜像
docker pull jaegertracing/all-in-one
3.1.3 运行镜像
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-p 5775:5775/udp \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 14268:14268 \
-p 14250:14250 \
-p 9411:9411 \
jaegertracing/all-in-one
3.1.4 访问ui
在浏览器中输入http://localhost:16686/,即可看到如下界面
到此jaeger我们已经安装成功了,接下来就需要在项目中进行实战
3.2 创建服务提供者
3.2.1 添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-spring-jaeger-cloud-starter</artifactId>
</dependency>
</dependencies>
关于依赖可以参考:github.com/opentracing…
3.2.2 添加服务接口
@RestController
public class OpentracingProviderController {
@GetMapping("/")
public String index() {
return "current request trace id:" + GlobalTracer.get().activeSpan().context().toTraceId();
}
}
3.2.3 设置应用名称
server:
port: 8081
spring:
application:
name: boot-cloud-opentracing-provider
如果不设置应用名称,在
jaeger-ui上看到的service就是unknown-spring-boot,为了方便管理服务,务必手动设置服务名称并确保其唯一性
3.3 创建服务消费者
3.3.1 添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-spring-jaeger-cloud-starter</artifactId>
</dependency>
</dependencies>
3.3.2 添加服务接口
@RestController
public class OpentracingConsumerController {
@Autowired
private RestTemplate restTemplate;
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@GetMapping("/")
public String index() {
Tracer tracer = GlobalTracer.get();
Span span = tracer.activeSpan();
String consumerTraceId = span.context().toTraceId();
String providerTraceId = restTemplate.getForObject("http://localhost:8081/", String.class);
return String.format("consumer trace id:%s,provider trace id:%s", consumerTraceId, providerTraceId);
}
}
3.3.3 设置应用名称
server:
port: 9090
spring:
application:
name: boot-cloud-opentracing-consumer
3.4 测试
- 启动服务提供者
- 启动服务消费者
- 访问服务消费者接口:http://localhost:9090/
打开jaeger-ui可以看到我们的分布式服务已经成功注册
3.5 查看链路追踪
在链路追踪详情里面,你可以很清晰的知道当前功能调用了哪些服务、以什么方式进行调用、耗时情况
3.6 trace id
当访问http://localhost:9090/接口后,接口会返回如下结果
consumer trace id:fdd4e764b323c8f0,provider trace id:current request trace id:fdd4e764b323c8f0
可以看到服务提供者和服务消费者使用的是同一个trace id,我们只需要在jaeger-ui的搜索框中输入trace id也可以查看对应的链路追踪信息。当然trace id也可以记录在日志中,这样当一个功能出现故障后,我们只需要根据trace id就可以搜索出与之相关的所有日志信息,可以大大缩短排查故障的时间。