场景
在系统中对请求链路根据版本信息进行服务调度,保证请求发送的请求链路的不同的版本服务上。文章来源:https://www.toymoban.com/news/detail-725157.html
方案
有很多开源组件支持链路追踪,如spring cloud sleuth。但支持场景有限,需要另行开发,故使用阿里的transmittable-thread-local进行实现,如默认的异步线程支持,rocketmq的数据传递等。文章来源地址https://www.toymoban.com/news/detail-725157.html
实现
- 引入transmittable-thread-local组件
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>2.14.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 创建请求拦截器并设置线程中的数据
import com.lizz.GrayHttpProperties;
import com.lizz.GrayParamHolder;
import org.apache.commons.lang.StringUtils;
import org.slf4j.MDC;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CustomHeaderInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String traceId = request.getHeader("traceId");
if (StringUtils.isNotBlank(traceId)) {
GrayParamHolder.putValue(GrayParamHolder.TRACE_ID, traceId);
// traceId添加到日志输出中
MDC.put(GrayParamHolder.TRACE_ID, traceId);
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
GrayParamHolder.clearValue();
MDC.clear();
}
}
- 添加拦截器到webmvc中
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Bean
public CustomHeaderInterceptor customHeaderInterceptor() {
return new CustomHeaderInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(customHeaderInterceptor());
}
}
- 线程数据管理工具
import com.alibaba.ttl.TransmittableThreadLocal;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class GrayParamHolder {
public static final String TRACE_ID = "traceId";
private static ThreadLocal<Map<String, String>> paramLocal = new TransmittableThreadLocal();
public static String getValue(String key) {
Map<String, String> paramMap = GrayParamHolder.paramLocal.get();
if (Objects.nonNull(paramMap) && !paramMap.isEmpty()) {
return paramMap.get(key);
}
return null;
}
public static void putValue(String key, String value) {
Map<String, String> paramMap = GrayParamHolder.paramLocal.get();
if (Objects.isNull(paramMap) || paramMap.isEmpty()) {
paramMap = new HashMap<>();
GrayParamHolder.paramLocal.set(paramMap);
}
paramMap.put(key, value);
}
public static void clearValue() {
GrayParamHolder.paramLocal.remove();
}
}
- 在Feign请求中增加数据传递
import feign.RequestInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
@Configuration
@Slf4j
public class FeignClientConfiguration {
@Bean
public RequestInterceptor requestInterceptor() {
return requestTemplate -> {
// 添加您的自定义标头
String traceId = GrayParamHolder.getValue(GrayParamHolder.TRACE_ID);
if (StringUtils.isNotBlank(traceId)) {
requestTemplate.header(GrayParamHolder.TRACE_ID, traceId);
}
};
}
}
到了这里,关于基于transmittable-thread-local的请求参数传递,如traceid,版本等的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!