在分布式系统中,一个请求往往会经过多个服务的处理。当系统出现问题时,定位问题变得十分困难,因为很难知道请求在各个服务之间的调用路径、每个服务的执行时间等信息。分布式链路追踪系统应运而生,Zipkin 就是其中一个非常流行的开源分布式链路追踪系统,它可以帮助我们收集、分析和可视化请求在分布式系统中的调用链路信息。
Zipkin 是 Twitter 开源的分布式链路追踪系统,基于 Google Dapper 论文设计而来。它通过收集和分析服务之间的调用信息,为开发者提供了请求的调用路径、每个服务的执行时间、调用依赖关系等详细信息,帮助开发者快速定位和解决分布式系统中的性能问题和故障。
可以从 Zipkin 的官方 GitHub 仓库(https://github.com/openzipkin/zipkin/releases)下载最新的 zipkin.jar
文件。
在命令行中运行以下命令启动 Zipkin Server:
java -jar zipkin.jar
启动成功后,访问 http://localhost:9411
可以看到 Zipkin 的管理界面。
使用 Spring Initializr(https://start.spring.io/)创建两个简单的 Spring Boot 项目,分别命名为 service-a
和 service-b
。
在 service-a
和 service-b
的 pom.xml
文件中添加以下依赖:
<dependencies>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud Sleuth -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth-zipkin</artifactId>
</dependency>
</dependencies>
在 service-a
和 service-b
的 application.properties
文件中添加以下配置:
spring.application.name=service-a # service-b 中改为 service-b
spring.zipkin.base-url=http://localhost:9411
spring.sleuth.sampler.probability=1.0
spring.sleuth.sampler.probability=1.0
表示采样率为 100%,即所有请求都会被追踪。
service-a
代码
package com.example.servicea;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@RestController
public class ServiceAApplication {
@Autowired
private RestTemplate restTemplate;
public static void main(String[] args) {
SpringApplication.run(ServiceAApplication.class, args);
}
@GetMapping("/call-service-b")
public String callServiceB() {
String response = restTemplate.getForObject("http://localhost:8081/hello", String.class);
return "Service A called Service B. Response: " + response;
}
}
service-b
代码
package com.example.serviceb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class ServiceBApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceBApplication.class, args);
}
@GetMapping("/hello")
public String hello() {
return "Hello from Service B!";
}
}
分别启动 service-a
(端口 8080)和 service-b
(端口 8081)。
访问 http://localhost:8080/call-service-b
,此时 service-a
会调用 service-b
的 /hello
接口。
访问 http://localhost:9411
,在 Zipkin 的管理界面中可以看到刚刚的请求调用链路信息。点击具体的 Trace ID 可以查看详细的 Span 信息,包括每个服务的执行时间、调用顺序等。
概念 | 描述 |
---|---|
Span | 基本工作单元,代表请求在某个服务中的一次调用 |
Trace | 由多个 Span 组成,代表一个完整的请求调用链路 |
Annotation | 用于记录 Span 中的特定事件 |
通过集成 Zipkin,我们可以方便地追踪分布式系统中请求的调用链路,快速定位和解决性能问题和故障。Spring Cloud Sleuth 提供了简单易用的 API,帮助我们在 Spring Boot 项目中轻松集成 Zipkin。在实际开发中,我们可以根据需要调整采样率,以平衡追踪信息的收集和系统性能的影响。
希望本文能帮助你理解和使用 Zipkin 进行分布式链路追踪。如果你在使用过程中遇到任何问题,欢迎查阅相关文档或社区论坛寻求帮助。