ctfshow-web261
2026/1/11 17:20:25
OpenTelemetry是 CNCF 的可观测性标准项目,提供统一的遥测数据收集和处理框架Java、Go、Python、JavaScript等多种编程语言Spring Boot Starter提供开箱即用的自动配置Spring Boot生态系统完美集成Span组成// Span 示例Spanspan=tracer.spanBuilder("operation-name").setAttribute("http.method","GET").setAttribute("http.url","/api/users").startSpan();try{// 执行业务逻辑}finally{span.end();}Span的名称,描述操作Span的关联Span之间的父子关系// Attributes 示例span.setAttribute("user.id",userId);span.setAttribute("request.size",requestSize);// Events 示例span.addEvent("message.received",Attributes.of(stringKey("message.id"),messageId));// application.yml 配置示例spring:application:name:user-serviceopentelemetry:endpoint:http://localhost:4317resource:attributes:service.name:${spring.application.name}traces:sampling:probability:1.0// Maven 配置<dependency><groupId>io.opentelemetry.instrumentation</groupId><artifactId>opentelemetry-spring-boot-starter</artifactId><version>2.3.0-alpha</version></dependency>// 可选:Jaeger 导出器<dependency><groupId>io.opentelemetry.instrumentation</groupId><artifactId>opentelemetry-exporter-jaeger</artifactId><version>2.3.0-alpha</version></dependency>// Gradle 配置 dependencies { implementation 'io.opentelemetry.instrumentation:opentelemetry-spring-boot-starter:2.3.0-alpha' implementation 'io.opentelemetry.instrumentation:opentelemetry-exporter-jaeger:2.3.0-alpha' }// application.yml 基础配置management:tracing:sampling:probability:1.0 // 采样概率,1.0 表示全部采样endpoints:web:exposure:include:health,info,traces,metrics // 暴露追踪端点 // OpenTelemetry 配置opentelemetry:endpoint:http://localhost:4317 // OTLP gRPC 端点protocol:grpc // 使用 gRPC 协议resource:attributes:service.name:user-service // 服务名称deployment.environment:production // 环境标识// 通过配置文件设置spring.application.name=user-service// 或通过代码设置@ConfigurationpublicclassOpenTelemetryConfig{@BeanpublicResourceotelResource(){returnResource.builder().put(ResourceAttributes.SERVICE_NAME,"user-service").put(ResourceAttributes.DEPLOYMENT_ENVIRONMENT,"production").build();}}// Jaeger 导出器配置opentelemetry:exporter:jaeger:endpoint:http://localhost:14250 // Jaeger gRPC 端点timeout:30s // Zipkin 导出器配置opentelemetry:exporter:zipkin:endpoint:http://localhost:9411/api/v2/spans@ConfigurationpublicclassTracingConfig{@BeanpublicSamplercustomSampler(){// 自定义采样策略returnSampler.parentBased(Sampler.traceIdRatioBased(0.1)// 10% 的请求会被采样);}}// 自定义资源属性opentelemetry:resource:attributes:service.name:user-serviceservice.version:1.0.0host.name:${HOSTNAME}cloud.region:us-east-1k8s.namespace:production@ComponentpublicclassCustomTracingInterceptor{@EventListenerpublicvoidhandleRequest(HttpServletRequestrequest){Span.current().setAttribute("custom.request.path",request.getRequestURI());Span.current().setAttribute("custom.user.agent",request.getHeader("User-Agent"));}}@RestController@RequestMapping("/api/users")publicclassUserController{@GetMapping("/{id}")publicResponseEntity<User>getUser(@PathVariableLongid){// 这个请求会自动被追踪Useruser=userService.findById(id);returnResponseEntity.ok(user);}@PostMappingpublicResponseEntity<User>createUser(@RequestBodyCreateUserRequestrequest){// 创建用户操作也会被追踪Useruser=userService.create(request);returnResponseEntity.status(HttpStatus.CREATED).body(user);}}Span@ServicepublicclassUserService{privatefinalRestTemplaterestTemplate;publicUserService(RestTemplaterestTemplate){this.restTemplate=restTemplate;}publicOrdergetOrder(LongorderId){// RestTemplate 调用会被自动追踪Stringurl="http://order-service/api/orders/"+orderId;returnrestTemplate.getForObject(url,Order.class);}}@ServicepublicclassUserService{privatefinalWebClientwebClient;publicUserService(WebClient.BuilderwebClientBuilder){this.webClient=webClientBuilder.build();}publicMono<Order>getOrderAsync(LongorderId){// WebClient 调用会被自动追踪returnwebClient.get().uri("/api/orders/{id}",orderId).retrieve().bodyToMono(Order.class);}}@RepositorypublicclassUserRepository{@AutowiredprivateJdbcTemplatejdbcTemplate;publicUserfindById(Longid){// SQL 查询会被自动追踪Stringsql="SELECT * FROM users WHERE id = ?";returnjdbcTemplate.queryForObject(sql,newUserRowMapper(),id);}publicvoidupdate(Useruser){// SQL 更新会被自动追踪Stringsql="UPDATE users SET name = ?, email = ? WHERE id = ?";jdbcTemplate.update(sql,user.getName(),user.getEmail(),user.getId());}}@Entity@Table(name="users")publicclassUser{@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateLongid;privateStringname;privateStringemail;// getters and setters}@RepositorypublicinterfaceUserRepositoryextendsJpaRepository<User,Long>{// 所有 JPA 操作都会被自动追踪List<User>findByNameContaining(Stringname);}@ServicepublicclassUserService{@AutowiredprivateUserRepositoryuserRepository;publicUsersaveUser(Useruser){// save 操作会被追踪returnuserRepository.save(user);}publicList<User>findUsersByName(Stringname){// 查询操作会被追踪returnuserRepository.findByNameContaining(name);}}@ServicepublicclassCacheService{@AutowiredprivateRedisTemplate<String,Object>redisTemplate;publicvoidsetCache(Stringkey,Objectvalue,Durationttl){// Redis 操作会被自动追踪redisTemplate.opsForValue().set(key,value,ttl);}publicObjectgetCache(Stringkey){// Redis 读取操作会被追踪returnredisTemplate.opsForValue().get(key);}}@ComponentpublicclassMessageProcessor{@KafkaListener(topics="user-events")publicvoidprocessUserEvent(ConsumerRecord<String,String>record){// Kafka 消息处理会被追踪Stringmessage=record.value();// 处理消息逻辑log.info("Processing user event: {}",message);}}@ServicepublicclassEventPublisher{@AutowiredprivateKafkaTemplate<String,String>kafkaTemplate;publicvoidpublishUserEvent(StringeventType,StringeventData){// Kafka 消息发送会被追踪kafkaTemplate.send("user-events",eventType,eventData);}}@ComponentpublicclassMessageHandler{@RabbitListener(queues="user.queue")publicvoidhandleUserMessage(Stringmessage){// RabbitMQ 消息处理会被追踪log.info("Received user message: {}",message);// 处理消息逻辑}}@ServicepublicclassMessagePublisher{@AutowiredprivateRabbitTemplaterabbitTemplate;publicvoidsendUserMessage(Stringmessage){