SpringCloud sleuth 在 spring-mvc 应用内 traceId 获取及使用
2026/8/22 12:22:49 网站建设 项目流程

目录

    • 1. MAVEN
      • 1.1. spring-cloud-starter-sleuth:2.0.0.RELEASE
      • 1.2. spring-cloud-starter-sleuth:3.0.0
    • 2. ​获取代码
      • 2.1. spring-cloud-starter-sleuth:2.0.0.RELEASE
      • 2.2. spring-cloud-starter-sleuth:3.0.0
    • 3. 为何可以如此获取?
    • 4. 实际项目中使用
    • 5. 日志中打印 traceId
    • 6. 特别注意

1. MAVEN

1.1. spring-cloud-starter-sleuth:2.0.0.RELEASE

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId><version>2.0.0.RELEASE</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-sleuth-core</artifactId><version>2.0.0.RELEASE</version></dependency><dependency><groupId>io.zipkin.brave</groupId><artifactId>brave-instrumentation-spring-webmvc</artifactId><version>5.1.0</version></dependency><dependency><groupId>io.zipkin.brave</groupId><artifactId>brave-instrumentation-servlet</artifactId><version>5.1.0</version></dependency>

1.2. spring-cloud-starter-sleuth:3.0.0

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId><version>3.0.0</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-sleuth-brave</artifactId><version>3.0.0</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-sleuth-instrumentation</artifactId><version>3.0.0</version></dependency>

2. ​获取代码

2.1. spring-cloud-starter-sleuth:2.0.0.RELEASE

// ServletServerHttpRequest requestTraceContexttraceContext=(TraceContext)request.getServletRequest().getAttribute(TraceContext.class.getName());StringtraceId=traceContext.traceIdString();// HttpServletRequest requestTraceContexttraceContext=(TraceContext)request.getAttribute(TraceContext.class.getName());StringtraceId=traceContext.traceIdString();

2.2. spring-cloud-starter-sleuth:3.0.0

// ServletServerHttpRequest requestTraceContexttraceContext=(TraceContext)request.getServletRequest().getAttribute(TraceContext.class.getName());StringtraceId=traceContext.traceId();// HttpServletRequest requestTraceContexttraceContext=(TraceContext)request.getAttribute(TraceContext.class.getName());StringtraceId=traceContext.traceId();

3. 为何可以如此获取?

版本所在 jar全路径
spring-cloud-starter-sleuth:2.0.0.RELEASEbrave-instrumentation-servletbrave.servlet.TracingFilter
spring-cloud-starter-sleuth:3.0.0spring-cloud-sleuth-instrumentationorg.springframework.cloud.sleuth.instrument.web.servlet.TracingFilter
publicfinalclassTracingFilterimplementsFilter{finalServletRuntimeservlet=ServletRuntime.get();finalCurrentTraceContextcurrentTraceContext;finalHttpServerHandler<HttpServerRequest,HttpServerResponse>handler;publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{HttpServletRequestreq=(HttpServletRequest)request;HttpServletResponseres=this.servlet.httpServletResponse(response);TraceContextcontext=(TraceContext)request.getAttribute(TraceContext.class.getName());if(context!=null){CurrentTraceContext.Scopescope=this.currentTraceContext.maybeScope(context);try{chain.doFilter(request,response);}finally{scope.close();}}else{Spanspan=this.handler.handleReceive(newHttpServletRequestWrapper(req));request.setAttribute(SpanCustomizer.class.getName(),span.customizer());// 赋值 traceIdrequest.setAttribute(TraceContext.class.getName(),span.context());......}}}

4. 实际项目中使用

packagecom.zxguan.springcloud2.user.config;importorg.springframework.core.MethodParameter;importorg.springframework.core.annotation.Order;importorg.springframework.http.MediaType;importorg.springframework.http.server.ServerHttpRequest;importorg.springframework.http.server.ServerHttpResponse;importorg.springframework.web.bind.annotation.RestControllerAdvice;importorg.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;@Order(0)@RestControllerAdvicepublicclassApiResponseAdviceimplementsResponseBodyAdvice{/** * 判断需要处理的情况 * * @param methodParameter * @param selectedHttpMessageConverter * * @return boolean true: false: */@Overridepublicbooleansupports(MethodParametermethodParameter,ClassselectedHttpMessageConverter){//returnfalse;}/** * 消息体返回前处理 * * @param body 返回的消息体 * @param methodParameter 响应类型 * @param mediaType 请求的响应 contentType * @param selectedHttpMessageConverter 执行序列化的转换器 * @param request * @param response * * @return Object 返回的消息体 */@OverridepublicObjectbeforeBodyWrite(Objectbody,MethodParametermethodParameter,MediaTypemediaType,ClassselectedHttpMessageConverter,ServerHttpRequestrequest,ServerHttpResponseresponse){// 此处可以统一添加 traceId 到响应中returnnull;}}

5. 日志中打印 traceId

借助MDC机制, 实现traceId的打印

<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %X{X-B3-TraceId} %X{X-B3-SpanId}</pattern>

6. 特别注意

  1. MDC设置X-B3-TraceId, 可以通过自定义过滤器提前到过滤器级别,但需要注意过滤器顺序,自定义过滤器需排在TracingFilter之后
  2. Spring Cloud2 + Sleuth 3 + OpenFeign存在设计缺陷,存在多个问题。其中就包括:@FeignClienturl写法会报错,为了尽可能保留 Sleuth 功能,需要使用RestTemplate或者HttpClient等实现接口访问,而非全局禁用配置spring.sleuth.feign.enabled=false

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询