为什么游戏引擎选纤程而不是线程:TaskScheduler纤程上下文切换原理剖析
2026/8/22 12:57:38
<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><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>// ServletServerHttpRequest requestTraceContexttraceContext=(TraceContext)request.getServletRequest().getAttribute(TraceContext.class.getName());StringtraceId=traceContext.traceIdString();// HttpServletRequest requestTraceContexttraceContext=(TraceContext)request.getAttribute(TraceContext.class.getName());StringtraceId=traceContext.traceIdString();// ServletServerHttpRequest requestTraceContexttraceContext=(TraceContext)request.getServletRequest().getAttribute(TraceContext.class.getName());StringtraceId=traceContext.traceId();// HttpServletRequest requestTraceContexttraceContext=(TraceContext)request.getAttribute(TraceContext.class.getName());StringtraceId=traceContext.traceId();| 版本 | 所在 jar | 全路径 |
|---|---|---|
| spring-cloud-starter-sleuth:2.0.0.RELEASE | brave-instrumentation-servlet | brave.servlet.TracingFilter |
| spring-cloud-starter-sleuth:3.0.0 | spring-cloud-sleuth-instrumentation | org.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());......}}}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;}}借助MDC机制, 实现traceId的打印
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %X{X-B3-TraceId} %X{X-B3-SpanId}</pattern>MDC设置X-B3-TraceId, 可以通过自定义过滤器提前到过滤器级别,但需要注意过滤器顺序,自定义过滤器需排在TracingFilter之后Spring Cloud2 + Sleuth 3 + OpenFeign存在设计缺陷,存在多个问题。其中就包括:@FeignClient的url写法会报错,为了尽可能保留 Sleuth 功能,需要使用RestTemplate或者HttpClient等实现接口访问,而非全局禁用配置spring.sleuth.feign.enabled=false