在分布式系统中,一个请求往往会经过多个服务的处理。当系统出现问题时,定位问题变得十分困难,因为很难知道请求在各个服务之间的调用路径、每个服务的执行时间等信息。分布式链路追踪系统应运而生,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-bspring.zipkin.base-url=http://localhost:9411spring.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@RestControllerpublic class ServiceAApplication {@Autowiredprivate 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@RestControllerpublic 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 进行分布式链路追踪。如果你在使用过程中遇到任何问题,欢迎查阅相关文档或社区论坛寻求帮助。