1.定义FeignSupportConfig
@Configuration public class FeignSupportConfig { @Bean public RequestInterceptor requestInterceptor(){ return new MyRequestInterceptor(); } @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
2.自定义RequestInterceptor
@Component public class MyRequestInterceptor implements RequestInterceptor { private static final String X_FORWARDED_FOR = "X-Forwarded-For"; private static final String PROXY_CLIENT_IP = "Proxy-Client-IP"; private static final String WL_PROXY_CLIENT_IP = "WL-Proxy-Client-IP"; private static final String X_REAL_IP = "X-Real-IP"; @Override public void apply(RequestTemplate requestTemplate) { if (RequestContextHolder.getRequestAttributes() == null) { return; } ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); String tokenHead = attributes.getRequest().getHeader(X_FORWARDED_FOR); if (!Strings.isNullOrEmpty(tokenHead) && !"null".equalsIgnoreCase(tokenHead)) { requestTemplate.header(X_FORWARDED_FOR, tokenHead); } String proxyHead = attributes.getRequest().getHeader(PROXY_CLIENT_IP); if (!Strings.isNullOrEmpty(proxyHead) && !"null".equalsIgnoreCase(proxyHead)) { requestTemplate.header(PROXY_CLIENT_IP, proxyHead); } String wlProxyHead = attributes.getRequest().getHeader(WL_PROXY_CLIENT_IP); if (!Strings.isNullOrEmpty(wlProxyHead) && !"null".equalsIgnoreCase(wlProxyHead)) { requestTemplate.header(WL_PROXY_CLIENT_IP, wlProxyHead); } String realHead = attributes.getRequest().getHeader(X_REAL_IP); if (!Strings.isNullOrEmpty(realHead) && !"null".equalsIgnoreCase(realHead)) { requestTemplate.header(X_REAL_IP, realHead); } } }
3.【核心】自定义HystrixConcurrencyStrategy,否则RequestContextHolder.getRequestAttributes()为null
@Component @Slf4j public class RequestAttributeStrategy extends HystrixConcurrencyStrategy { public RequestAttributeStrategy() { HystrixPlugins.reset(); HystrixPlugins.getInstance().registerConcurrencyStrategy(this); } @Override public <T> Callable<T> wrapCallable(Callable<T> callable) { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); return new WrappedCallable<>(callable, requestAttributes); } 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 { RequestContextHolder.setRequestAttributes(requestAttributes); return target.call(); } finally { RequestContextHolder.resetRequestAttributes(); } } } }