排查开启Hystrix导致下游服务请求头丢失问题
1、背景介绍
看过我文章的博友应该记得之前为了解决服务雪崩问题整合过Hystrix熔断降级。不熟悉的整合的可以再去看看。直通车。
回规正题,在整合上线一段时间后,服务熔断降级问题得于解决,但最近用户经常反馈在不同平台之间登陆账号会互相挤下来。接到问题后就开始排查,先上一张生产日志图,相信熟悉的小伙伴应该能才到问题所在了。
2、问题重现
通常解决问题,我们得先发现问题,只有找到问题发现的原因才能着手解决它。回到上面那张生产日志截图,相信大家都猜到了问题出现的原因,没错,Hystrix在开发feign链路的时候是用的子线程去调用的接口,看过源码知道request是通过ThreadLocal在当前线程中传输的,通过子线程拿不到request也就不奇怪了。
接下来我们先本地模拟下问题发生原因,首先在上游服务中先开启Hystrix熔断服务,在yml文件中加入以下配置即可。
# hystrix 配置,true表示开启,false关闭
feign:
hystrix:
enabled: true
加入上面配置后,我们分别设置false和true去模拟请求,并在下游服务打印request信息。发现在设置为true的情况下,是拿不到我们的request中的head的。
既然我们知道问题是由于父子线程传输问题导致了,那是不是解决这个传输问题就解决问题了,直接上代码看效果
/**
* Feign 配置注册,需要注意这个类得导入下@Import({FeignAutoConfiguration.class})
*/
@Configuration
public class FeignAutoConfiguration {
@Bean
public RequestInterceptor requestInterceptor() {
return new FeignRequestInterceptor();
}
@PostConstruct
public void hystrixConcurrencyStrategy() {
HystrixPlugins.getInstance().registerConcurrencyStrategy(new FeignHystrixConcurrencyStrategy());
}
}
/**
* Hystrix 子线程无法获取request问题,重写传输策略,将主线程的request传到下级
* feign.hystrix.enabled 当该属性为true时候该策略才会生效
*/
public class FeignHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {