附上原文作者: http://www.itmuch.com/spring-cloud-sum/hystrix-threadlocal/
#服务熔断
feign.hystrix.enabled = true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds = 5000
这是我在公司开发项目时配置熔断的时候踩的一个坑,接下来贴上来一般常用的拦截器所用的一段代码
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
当你开启熔断后会遇到一个问题就是attributes取到的上下文为空,这是因为Hystrix有隔离策略:THREAD和SEMAPHORE,所以当你的隔离策略为THREAD的时候是拿不到Threadlocal里面的值的。
这边我用了两种方法直接贴上我的解决方案:
第一种:
直接添加配置修改默认的隔离策略:
#服务熔断
feign.hystrix.enabled = true
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds = 5000
hystrix.command.default.execution.isolation.strategy = SEMAPHORE
修改配置文件把默认策略改成SEMAPHORE就能拿到ThreadLoacl里的值了当然不推荐这样做
第二种:
创建一个重写类
package com.jusda.common.Interceptor;
import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import java.util.concurrent.Callable;
/**
* @author wanglinfeng
* @version 1.0
* @className RequestAttributeHystrixConcurrencyStrategy
* @description 获取开启Hystrix后的上下文封装
* @date 2019/8/12 9:32
*/
public class RequestAttributeHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
private static final Logger logger= LoggerFactory.getLogger(RequestAttributeHystrixConcurrencyStrategy.class);
public RequestAttributeHystrixConcurrencyStrategy(){
HystrixPlugins.reset();
HystrixPlugins.getInstance().registerConcurrencyStrategy(this);
}
/**
* 装饰线程hystrix callable
*
* @return {@link Callable}
*/
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable ){
RequestAttributes requestAttribute = RequestContextHolder.getRequestAttributes();
return new WrappedCallable<>(callable,requestAttribute);
}
static class WrappedCallable<T> implements Callable<T>{
private final Callable<T> target;
private final RequestAttributes requestAttributes;
public WrappedCallable(Callable<T> target,RequestAttributes requestAttributes){
this.target = target;
this.requestAttributes = requestAttributes;
}
@Override
public T call() throws Exception{
try {
//在调用call方法前,我们可以将当前上下文信息放入
RequestContextHolder.setRequestAttributes(requestAttributes);
//call()传播上下文信息
return target.call();
}finally {
RequestContextHolder.resetRequestAttributes();
}
}
}
}
如图所示自定义并发策略重写wrapCallable继承HystrixConcurrencyStrategy
此代码经测试能正常工作。