在使用spring cloud的时候,多个微服务之间相互调用。很容易出现用户信息传递或者token传递的情况。
我们实现feign提供的RequestInterceptor
加人要传递的数据。
@Configuration
public class TransmitUserFeignClientInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
UserInfo userInfo = UserHandler.get();
List<String> cookies = new ArrayList<>();
cookies.add("userId=" + userInfo.getId());
requestTemplate.header(HttpHeaders.COOKIE, cookies);
}
}
public class UserHandler {
static final String SESSION_USERID = "SESSION_USERID";
private static ThreadLocal<UserInfo> user = new ThreadLocal<UserInfo>() {
@Override
protected UserInfo initialValue() {
return null;
}
};
public static void set(UserInfo userInfo) {
user.set(userInfo);
}
public static UserInfo get() {
return user.get();
}
public static void clear() {
user.remove();
}
}
在服务当中在加入过滤器和拦截器,都可以实现对request的拦截,然后取出cookie中的值,后面怎么做不需要所了吧。
太妙了,成功那到cookie。
但是 仅限于feign.hystrix.enabled
为false
的时候,如果为true
则取到的是NULL
。容我默哀3分钟…
这是因为feign开启了hystrix后,hystrix默认使用了线程了隔离策略。
将隔离策略改为:SEMAPHORE
hystrix.command.default.execution.isolation.strategy: SEMAPHORE
但是这不是官方推荐的
继承HystrixConcurrencyStrategy
,重写wrapCallable方法。
@Component
public class RequestHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
private final Logger log = LoggerFactory.getLogger(RequestHystrixConcurrencyStrategy.class);
private HystrixConcurrencyStrategy delegate;
public RequestHystrixConcurrencyStrategy() {
try {
this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy();
if (this.delegate instanceof RequestHystrixConcurrencyStrategy) {
return;
}
HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance().getCommandExecutionHook();
HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier();
HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance().getMetricsPublisher();
HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance().getPropertiesStrategy();
this.logCurrentStateOfHystrixPlugins(eventNotifier, metricsPublisher, propertiesStrategy);
HystrixPlugins.reset();
HystrixPlugins.getInstance().registerConcurrencyStrategy(this);
HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
} catch (Exception e) {
log.error("Failed to register Sleuth Hystrix Concurrency Strategy", e);
}
}
private void logCurrentStateOfHystrixPlugins(HystrixEventNotifier eventNotifier,
HystrixMetricsPublisher metricsPublisher,
HystrixPropertiesStrategy propertiesStrategy) {
if (log.isDebugEnabled()) {
log.debug("Current Hystrix plugins configuration is ["
+ "concurrencyStrategy [" + this.delegate + "]," + "eventNotifier ["
+ eventNotifier + "]," + "metricPublisher [" + metricsPublisher + "],"
+ "propertiesStrategy [" + propertiesStrategy + "]," + "]");
log.debug("Registering Sleuth Hystrix Concurrency Strategy.");
}
}
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
return new WrappedCallable(callable, UserHandler.get());
}
@Override
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize, HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
return this.delegate.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties threadPoolProperties) {
return this.delegate.getThreadPool(threadPoolKey, threadPoolProperties);
}
@Override
public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) {
return this.delegate.getBlockingQueue(maxQueueSize);
}
@Override
public <T> HystrixRequestVariable<T> getRequestVariable(HystrixRequestVariableLifecycle<T> rv) {
return this.delegate.getRequestVariable(rv);
}
static class WrappedCallable<T> implements Callable<T> {
private final Callable<T> targer;
private final UserInfo userInfo;
public WrappedCallable(Callable<T> targer, UserInfo userInfo) {
this.targer = targer;
this.userInfo = userInfo;
}
@Override
public T call() throws Exception {
UserHandler.set(userInfo);
return targer.call();
}
}
}
参考:https://blog.csdn.net/liu_ares/article/details/100371441