Spring Cloud Sleuth实现分布式服务追踪
使用Spring Cloud Sleuth为微服务系统添加分布式追踪能力,通过唯一标识符关联跨服务调用日志。
环境准备
1. 服务注册中心
部署Eureka Server作为服务发现组件。
2. 创建服务调用方service-a
实现REST端点/invoke,通过Ribbon调用下游服务:
// 应用配置
spring.application.name=service-a
server.port=9001
eureka.client.service-url.default-zone=http://localhost:1001/eureka/
@RestController
public class ServiceAController {
@Autowired
private RestTemplate client;
@GetMapping("/invoke")
public String execute() {
return client.getForEntity("http://service-b/response", String.class).getBody();
}
}
@Configuration
class AppConfig {
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
3. 创建服务提供方service-b
提供/response端点供service-a调用:
// 应用配置
spring.application.name=service-b
server.port=9002
eureka.client.service-url.default-zone=http://localhost:1001/eureka/
@RestController
public class ServiceBController {
@GetMapping("/response")
public String process() {
return "ServiceResponse";
}
}
4. 验证基础调用
启动Eureka、service-a和service-b后,请求http://localhost:9001/invoke返回"ServiceResponse"。日志显示独立服务记录:
// service-a日志
INFO ServiceAController: ServiceA request initiated
// service-b日志
INFO ServiceBController: Processing request
集成追踪功能
5. 添加Sleuth依赖
在service-a和service-b的pom.xml中添加:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
6. 观察追踪日志
重启服务后请求相同接口,日志新增追踪标识:
// service-a日志
INFO [service-a,8da1b3f472c584a2,8da1b3f472c584a2,true] ServiceAController: ServiceA request initiated
// service-b日志
INFO [service-b,8da1b3f472c584a2,6c4f8921e539b0d1,true] ServiceBController: Processing request
追踪标识解析
- 应用名称:
spring.application.name配置值 - Trace ID:请求链路唯一标识(示例中
8da1b3f472c584a2) - Span ID:单个工作单元标识(service-a中
8da1b3f472c584a2,service-b中6c4f8921e539b0d1) - 采样标志:控制日志是否输出到收集器
7. 通信过程增强
Sleuth自动在HTTP头注入追踪参数:
- X-B3-TraceId:链路追踪ID
- X-B3-SpanId:当前操作单元ID
- X-B3-ParentSpanId:父单元ID(首节点为空)
8. 自定义追踪日志
在service-b中获取并记录HTTP头信息:
@RestController
public class ServiceBController {
@GetMapping("/response")
public String process(HttpServletRequest req) {
logger.info("TraceID={}, SpanID={}",
req.getHeader("X-B3-TraceId"),
req.getHeader("X-B3-SpanId"));
return "ServiceResponse";
}
}
9. 启用详细日志
在application.properties添加:
logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG
DEBUG日志将显示请求处理全过程与追踪ID关联。