博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
feign调用接口session丢失解决方案
阅读量:5896 次
发布时间:2019-06-19

本文共 7372 字,大约阅读时间需要 24 分钟。

微服务使用feign相互之间调用时,因为feign默认不传输Header,存在session丢失的问题。例如,使用Feign调用某个远程API,这个远程API需要传递一个鉴权信息,我们可以把cookie里面的session信息放到Header里面,这个Header是动态的,跟你的HttpRequest相关,我们选择编写一个拦截器来实现Header的传递,也就是需要实现RequestInterceptor接口,详细代码如下:

1.新建feign配置类FeignConfig.java,它包含一个外部hystrix自定义隔离策略类FeignHystrixConcurrencyStrategy.java继承hystrix隔离策略HystrixConcurrencyStrategy ,并且这个自定义策略类作为bean配置到feign的配置类FeignConfig中

package webapp.conf;import com.netflix.hystrix.HystrixThreadPoolKey;import com.netflix.hystrix.HystrixThreadPoolProperties;import com.netflix.hystrix.strategy.HystrixPlugins;import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable;import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle;import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;import com.netflix.hystrix.strategy.properties.HystrixProperty;import feign.RequestInterceptor;import feign.RequestTemplate;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.context.annotation.Bean;import org.springframework.web.context.request.RequestAttributes;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;import java.util.Enumeration;import java.util.concurrent.BlockingQueue;import java.util.concurrent.Callable;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class FeignConfig implements RequestInterceptor {    @Bean    public FeignHystrixConcurrencyStrategy feignHystrixConcurrencyStrategy() {        return new FeignHystrixConcurrencyStrategy();    }    @Override    public void apply(RequestTemplate template) {        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();        if (requestAttributes == null) {            return;        }        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();        Enumeration
headerNames = request.getHeaderNames(); if (headerNames != null) { while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); Enumeration
values = request.getHeaders(name); while (values.hasMoreElements()) { String value = values.nextElement(); template.header(name, value); } } } }}class FeignHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy { private static final Logger log = LoggerFactory.getLogger(FeignHystrixConcurrencyStrategy.class); private HystrixConcurrencyStrategy delegate; FeignHystrixConcurrencyStrategy() { try { this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy(); if (this.delegate instanceof FeignHystrixConcurrencyStrategy) { // Welcome to singleton hell... 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
Callable
wrapCallable(Callable
callable) { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); return new WrappedCallable<>(callable, requestAttributes); } @Override public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixProperty
corePoolSize, HystrixProperty
maximumPoolSize, HystrixProperty
keepAliveTime, TimeUnit unit, BlockingQueue
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
getBlockingQueue(int maxQueueSize) { return this.delegate.getBlockingQueue(maxQueueSize); } @Override public
HystrixRequestVariable
getRequestVariable(HystrixRequestVariableLifecycle
rv) { return this.delegate.getRequestVariable(rv); } static class WrappedCallable
implements Callable
{ private final Callable
target; private final RequestAttributes requestAttributes; WrappedCallable(Callable
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(); } } }}

2.在@FeignClient里配置上面的配置类,如下:

package webapp.userFeign;import org.springframework.cloud.netflix.feign.FeignClient;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import webapp.conf.FeignConfig;@FeignClient(name = "user", fallback = UserFeignFallBack.class, configuration = FeignConfig.class)public interface UserFeign {    @RequestMapping(value = "/user/findUser", method = RequestMethod.GET)    String findUser();    @RequestMapping(value = "/user/findLUser", method = RequestMethod.GET)    String findLUser();}

 

转载于:https://www.cnblogs.com/007sx/p/9668719.html

你可能感兴趣的文章
[C#学习] BindingNavigator控件
查看>>
算法:翻转单词顺序列
查看>>
Object.assign和序列/反序列
查看>>
Git远程操作详解【转】
查看>>
Git 创建仓库【转】
查看>>
2级DataList嵌套
查看>>
tomcat:javax.servlet.http.HttpServletRequest cannot be resolved
查看>>
在linux通过kubeadm搭建kubernetes群集
查看>>
char varchar
查看>>
读博士的五个阶段
查看>>
[bzoj1787][Ahoi2008]Meet 紧急集合
查看>>
iOS开发——面试篇&面试总结(六)内存问题
查看>>
《Spring1之第六次站立会议》
查看>>
图片照片类的封装(不是相册)
查看>>
javascript 原型详解
查看>>
移动端web产品开发框架appframework浅探
查看>>
NYOJ_246_Human Gene Functions
查看>>
多线程篇七:通过Callable和Future获取线程池中单个务完成后的结果
查看>>
Android UI:Layout 自定义标题栏
查看>>
Android:LayoutInflater载入没有载入或想动态载入的layout
查看>>