Feign拦截器中获取为空问题排查

时间:2025-02-13 10:33:47
public class RequestHeaderHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy { private final HystrixConcurrencyStrategy existingConcurrencyStrategy; public RequestHeaderHystrixConcurrencyStrategy(HystrixConcurrencyStrategy existingConcurrencyStrategy) { this.existingConcurrencyStrategy = existingConcurrencyStrategy; } @Override public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) { return existingConcurrencyStrategy != null ? existingConcurrencyStrategy.getBlockingQueue(maxQueueSize) : super.getBlockingQueue(maxQueueSize); } @Override public <T> HystrixRequestVariable<T> getRequestVariable(HystrixRequestVariableLifecycle<T> rv) { return existingConcurrencyStrategy != null ? existingConcurrencyStrategy.getRequestVariable(rv) : super.getRequestVariable(rv); } @Override public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize, HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { return existingConcurrencyStrategy != null ? existingConcurrencyStrategy.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue) : super.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } @Override public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties threadPoolProperties) { return existingConcurrencyStrategy != null ? existingConcurrencyStrategy.getThreadPool(threadPoolKey, threadPoolProperties) : super.getThreadPool(threadPoolKey, threadPoolProperties); } @Override public <T> Callable<T> wrapCallable(Callable<T> callable) { Map<String, String> headers = AuthenticationContextHolder.getRequestHeaders(); SysUser userInfo = AuthenticationContextHolder.getUserInfo(); return existingConcurrencyStrategy != null ? existingConcurrencyStrategy.wrapCallable(new WrappedCallable<T>(callable, headers, userInfo)) : super.wrapCallable(new WrappedCallable<T>(callable, headers, userInfo)); } static class WrappedCallable<T> implements Callable<T> { private final Callable<T> callable; private final Map<String, String> headers; private final SysUser userInfo; public WrappedCallable(Callable<T> callable, Map<String, String> headers, SysUser userInfo) { this.callable = callable; this.headers = headers; this.userInfo = userInfo; } @Override public T call() throws Exception { try { AuthenticationContextHolder.setRequestHeaders(headers); AuthenticationContextHolder.setUserInfo(userInfo); return callable.call(); } finally { AuthenticationContextHolder.remove(); } } } } @Configuration(proxyBeanMethods = false) @ConditionalOnProperty(name = "", havingValue = "true") @Slf4j public class HystrixConcurrencyStrategyAutoConfiguration { @Autowired(required = false) private HystrixConcurrencyStrategy existingConcurrencyStrategy; @PostConstruct public void init() { HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier(); HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance().getMetricsPublisher(); HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance().getPropertiesStrategy(); HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance().getCommandExecutionHook(); HystrixConcurrencyStrategy concurrencyStrategy = detectRegisteredConcurrencyStrategy(); HystrixPlugins.reset(); // 注册Hystrix并发策略以外的插件 HystrixPlugins.getInstance().registerConcurrencyStrategy(new RequestHeaderHystrixConcurrencyStrategy(concurrencyStrategy)); HystrixPlugins.getInstance().registerEventNotifier(eventNotifier); HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher); HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy); HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook); } private HystrixConcurrencyStrategy detectRegisteredConcurrencyStrategy() { HystrixConcurrencyStrategy registeredStrategy = HystrixPlugins.getInstance().getConcurrencyStrategy(); if (existingConcurrencyStrategy == null) { return registeredStrategy; } if (registeredStrategy instanceof HystrixConcurrencyStrategyDefault) { return existingConcurrencyStrategy; } if (!existingConcurrencyStrategy.equals(registeredStrategy)) { log.warn("找到多个 HystrixConcurrencyStrategy, 使用已存在的HystrixConcurrencyStrategy"); } return existingConcurrencyStrategy; } } @Component public class FeignRequestInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attributes != null) { HttpServletRequest request = attributes.getRequest(); Enumeration<String> headerNames = request.getHeaderNames(); if (headerNames != null) { while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); String values = request.getHeader(name); requestTemplate.header(name, values); } } } else { // RequestContextHolder中获取不到request时,可能是当前线程在Hystrix线程池中,则需要从AuthenticationontextHolder中获取header信息 Map<String, String> headers = AuthenticationContextHolder.getRequestHeaders(); if (MapUtils.isNotEmpty(headers)) { headers.forEach(requestTemplate::header); } } } }