分布式系统追踪者Jaeger

997 阅读3分钟

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-agentjaeger-collectordbjaeger-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 测试

打开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就可以搜索出与之相关的所有日志信息,可以大大缩短排查故障的时间。

4. 代码地址

boot-cloud-opentracing