1.什么是 Micrometer Tracing?
Micrometer Tracing 是一个用于微服务架构的追踪库,它提供了一种简单而强大的方式来收集和报告分布式系统中的性能和调用链信息。它是 Micrometer 库的一部分,Micrometer 是一个用于应用程序监控的指标收集工具,支持多种监控系统,如 Prometheus、Graphite 和 InfluxDB。
Micrometer Tracing 旨在帮助开发者和运维人员理解微服务之间的交互,识别性能瓶颈,并提高系统的可观察性。通过追踪请求的生命周期,Micrometer Tracing 可以提供详细的调用链信息,帮助团队快速定位问题。
Micrometer Tracing 的优势
- 简单易用:Micrometer Tracing 提供了简单的注解和 API,使得在应用程序中添加追踪变得非常容易。
- 与 Micrometer 生态系统集成:作为 Micrometer 的一部分,Micrometer Tracing 可以与其他监控工具无缝集成,提供全面的监控解决方案。
- 灵活的采样策略:用户可以根据需求自定义采样策略,以平衡追踪的详细程度和性能开销。
- 丰富的上下文信息:通过 Tags 和 Span,用户可以获得丰富的上下文信息,帮助快速定位问题。
Micrometer Tracing 的核心概念
-
Span:Span 是追踪的基本单位,表示一个操作的开始和结束。每个 Span 都有一个唯一的标识符(Span ID),并且可以包含父 Span 的信息,从而形成一个调用链。
-
Trace:Trace 是由多个 Span 组成的,表示一个请求在系统中的完整生命周期。每个 Trace 都有一个唯一的标识符(Trace ID),可以用来追踪整个请求的路径。
-
Tags:Tags 是附加到 Span 上的键值对,用于提供额外的上下文信息,例如服务名称、方法名称、状态码等。Tags 可以帮助用户更好地理解和分析追踪数据。
-
Sampler:Sampler 决定哪些请求将被追踪。可以根据请求的特征(如请求类型、服务名称等)配置采样策略,以减少性能开销。
2.环境搭建
pull images
bash
docker pull openzipkin/zipkin
run docker
arduino
docker run -d -p 9411:9411 openzipkin/zipkin
web UI
3.代码工程
实验目标
在 Spring Cloud 应用程序中使用 Micrometer Tracing
添加依赖
在 pom.xml
中添加 Micrometer Tracing 和 Spring Cloud Sleuth 的依赖:
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springcloud-demo</artifactId>
<groupId>com.et</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-sleuth</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
配置类
java
package com.et.config;
import io.micrometer.observation.ObservationRegistry;
import io.micrometer.observation.aop.ObservedAspect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ObservedAspectConfiguration {
@Bean
public ObservedAspect observedAspect(ObservationRegistry observationRegistry) {
observationRegistry.observationConfig().observationHandler(new SimpleLoggingHandler());
return new ObservedAspect(observationRegistry);
}
}
package com.et.config;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationHandler;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SimpleLoggingHandler implements ObservationHandler<Observation.Context> {
@Override
public void onStart(Observation.Context context) {
ObservationHandler.super.onStart(context);
log.info("Starting context {} ", context);
}
@Override
public void onError(Observation.Context context) {
ObservationHandler.super.onError(context);
}
@Override
public void onEvent(Observation.Event event, Observation.Context context) {
ObservationHandler.super.onEvent(event, context);
}
@Override
public void onScopeOpened(Observation.Context context) {
ObservationHandler.super.onScopeOpened(context);
}
@Override
public void onScopeClosed(Observation.Context context) {
ObservationHandler.super.onScopeClosed(context);
}
@Override
public void onScopeReset(Observation.Context context) {
ObservationHandler.super.onScopeReset(context);
}
@Override
public void onStop(Observation.Context context) {
ObservationHandler.super.onStop(context);
log.info("Stopping context {} ", context);
}
@Override
public boolean supportsContext(Observation.Context context) {
return true;
}
}
为了使tracking的newspan注解生效,需要额外配置如下
kotlin
package com.et.config;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.annotation.DefaultNewSpanParser;
import io.micrometer.tracing.annotation.ImperativeMethodInvocationProcessor;
import io.micrometer.tracing.annotation.MethodInvocationProcessor;
import io.micrometer.tracing.annotation.NewSpanParser;
import io.micrometer.tracing.annotation.SpanAspect;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class SpanAspectConfiguration {
@Bean
NewSpanParser newSpanParser() {
return new DefaultNewSpanParser();
}
@Bean
MethodInvocationProcessor methodInvocationProcessor(
NewSpanParser newSpanParser, Tracer tracer, BeanFactory beanFactory) {
return new ImperativeMethodInvocationProcessor(
newSpanParser, tracer, beanFactory::getBean, beanFactory::getBean);
}
@Bean
SpanAspect spanAspect(MethodInvocationProcessor methodInvocationProcessor) {
return new SpanAspect(methodInvocationProcessor);
}
}
启用 Tracing:
在 Spring Boot 的主类上添加 @EnableAspectJAutoProxy
注解,以启用 AOP 支持:
typescript
package com.et;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication
@EnableAspectJAutoProxy
public class SpringCloudApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudApplication.class, args);
}
}
使用注解:
在需要追踪的方法上使用 @NewSpan
注解,以创建新的 Span。例如:
kotlin
package com.et.service;
import io.micrometer.tracing.annotation.NewSpan;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @author liuhaihua
* @version 1.0
* @ClassName DemoService
* @Description todo
* @date 2024/12/03/ 17:37
*/
@Service
@Slf4j
public class DemoService {
@NewSpan
public String sayHello(String name){
log.info("hello "+name);
return "hello "+name;
}
}
controller
kotlin
package com.et.controller;
import io.micrometer.tracing.SpanName;
import io.micrometer.tracing.annotation.NewSpan;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class MyController {
@Autowired
com.et.service.DemoService demoService;
@GetMapping("/hello")
@NewSpan
@SpanName("customSpanName")
public String hello() {
log.info("into controller ");
return demoService.sayHello("jack");
}
}
application.yml
yaml
spring.application.name: demo-tracing
server:
port: 8088
servlet:
context-path: /app
logging.pattern.level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"
management:
zipkin:
tracing:
endpoint: http://localhost:9411/api/v2/spans
tracing:
sampling:
probability: 1.0
以上只是一些关键代码,所有代码请参见下面代码仓库
代码仓库
- github.com/Harries/spr...(Spring Cloud Sleuth)
4.测试
启动Spring Cloud应用
访问rest api
访问http://127.0.0.1:8088/app/hello,控制台输出日志
ini
2024-12-03T18:18:30.845+08:00 INFO [demo-tracing,d0f7eb048278e2374cf99e898d8cffb9,59da48fe2de9af72] 13304 --- [demo-tracing] [nio-8088-exec-4] [d0f7eb048278e2374cf99e898d8cffb9-59da48fe2de9af72] com.et.controller.MyController : into controller
2024-12-03T18:18:30.846+08:00 INFO [demo-tracing,d0f7eb048278e2374cf99e898d8cffb9,62a3992306bc6344] 13304 --- [demo-tracing] [nio-8088-exec-4] [d0f7eb048278e2374cf99e898d8cffb9-62a3992306bc6344] com.et.service.DemoService : hello jack
查看追踪数据:
Micrometer Tracing 会自动收集追踪数据,并将其发送到配置的zipkin。你可以使用这些数据来分析请求的性能和调用链。
5.结论
Micrometer Tracing 是一个强大的工具,可以帮助开发者和运维人员更好地理解和监控微服务架构中的请求流。通过简单的配置和使用,Micrometer Tracing 可以显著提高系统的可观察性,帮助团队快速识别和解决性能问题。在现代微服务架构中,采用 Micrometer Tracing 是提升应用程序性能和可靠性的有效手段。