日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

feign调用session丢失解决方案

發布時間:2025/3/21 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 feign调用session丢失解决方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ?最近在做項目的時候發現,微服務使用feign相互之間調用時,存在session丟失的問題。例如,使用Feign調用某個遠程API,這個遠程API需要傳遞一個鑒權信息,我們可以把cookie里面的session信息放到Header里面,這個Header是動態的,跟你的HttpRequest相關,我們選擇編寫一個攔截器來實現Header的傳遞,也就是需要實現RequestInterceptor接口,具體代碼如下:

@Configuration @EnableFeignClients(basePackages = "com.xxx.xxx.client") public class FeignClientsConfigurationCustom implements RequestInterceptor { @Override public void apply(RequestTemplate template) { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); if (requestAttributes == null) { return; } HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); Enumeration<String> headerNames = request.getHeaderNames(); if (headerNames != null) { while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); Enumeration<String> values = request.getHeaders(name); while (values.hasMoreElements()) { String value = values.nextElement(); template.header(name, value); } } } } }

經過測試,上面的解決方案可以正常的使用;?

但是,當引入Hystrix熔斷策略時,出現了一個新的問題:

RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

此時requestAttributes會返回null,從而無法傳遞session信息,最終發現RequestContextHolder.getRequestAttributes(),該方法是從ThreadLocal變量里面取得對應信息的,這就找到問題原因了,是由于Hystrix熔斷機制導致的。?
Hystrix有2個隔離策略:THREAD以及SEMAPHORE,當隔離策略為 THREAD 時,是沒辦法拿到 ThreadLocal 中的值的。

因此有兩種解決方案:

方案一:調整格隔離策略:

hystrix.command.default.execution.isolation.strategy: SEMAPHORE

這樣配置后,Feign可以正常工作。

但該方案不是特別好。原因是Hystrix官方強烈建議使用THREAD作為隔離策略! 可以參考官方文檔說明。

方案二:自定義策略

記得之前在研究zipkin日志追蹤的時候,看到過Sleuth有自己的熔斷機制,用來在thread之間傳遞Trace信息,Sleuth是可以拿到自己上下文信息的,查看源碼找到了?
org.springframework.cloud.sleuth.instrument.hystrix.SleuthHystrixConcurrencyStrategy?
這個類,查看SleuthHystrixConcurrencyStrategy的源碼,繼承了HystrixConcurrencyStrategy,用來實現了自己的并發策略。

/*** Abstract class for defining different behavior or implementations for concurrency related aspects of the system with default implementations.* <p>* For example, every {@link Callable} executed by {@link HystrixCommand} will call {@link #wrapCallable(Callable)} to give a chance for custom implementations to decorate the {@link Callable} with* additional behavior.* <p>* When you implement a concrete {@link HystrixConcurrencyStrategy}, you should make the strategy idempotent w.r.t ThreadLocals.* Since the usage of threads by Hystrix is internal, Hystrix does not attempt to apply the strategy in an idempotent way.* Instead, you should write your strategy to work idempotently. See https://github.com/Netflix/Hystrix/issues/351 for a more detailed discussion.* <p>* See {@link HystrixPlugins} or the Hystrix GitHub Wiki for information on configuring plugins: <a* href="https://github.com/Netflix/Hystrix/wiki/Plugins">https://github.com/Netflix/Hystrix/wiki/Plugins</a>.*/ public abstract class HystrixConcurrencyStrategy

搜索發現有好幾個地方繼承了HystrixConcurrencyStrategy類?

其中就有我們熟悉的Spring Security和剛才提到的Sleuth都是使用了自定義的策略,同時由于Hystrix只允許有一個并發策略,因此為了不影響Spring Security和Sleuth,我們可以參考他們的策略實現自己的策略,大致思路:?
將現有的并發策略作為新并發策略的成員變量;?
在新并發策略中,返回現有并發策略的線程池、Queue;?
代碼如下:

public class FeignHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy { private static final Logger log = LoggerFactory.getLogger(FeignHystrixConcurrencyStrategy.class); private HystrixConcurrencyStrategy delegate; public 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 <T> Callable<T> wrapCallable(Callable<T> callable) { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); return new WrappedCallable<>(callable, requestAttributes); } @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> 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(); } } } }

最后,將這個策略類作為bean配置到feign的配置類FeignClientsConfigurationCustom

@Beanpublic FeignHystrixConcurrencyStrategy feignHystrixConcurrencyStrategy() {return new FeignHystrixConcurrencyStrategy();}

至此,結合FeignClientsConfigurationCustom配置feign調用session丟失的問題完美解決。

?

總結

以上是生活随笔為你收集整理的feign调用session丢失解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 免看黄大片aa | av黄色在线免费观看 | 日本毛片在线看 | 精品人妻一区二区三区久久 | 一区二区三区国 | 天天5g天天爽免费观看 | 加勒比成人在线 | 亚洲最大成人在线 | 国产高清视频免费观看 | 国产成人aaa| 少妇一级1淫片 | 国产又粗又猛又爽又黄91精品 | 亚洲另类xxxx | 绯色av蜜臀vs少妇 | 麻豆www| 女~淫辱の触手3d动漫 | 免费av毛片 | 国产高清色 | 一本大道熟女人妻中文字幕在线 | 蜜桃av乱码一区二区三区 | 欧美 日韩 国产 中文 | 国产对白在线 | 91干视频 | 人人妻人人澡人人爽人人欧美一区 | 夜夜爱爱| 亚洲精品久久久久久 | 欧美一区一区 | 日韩的一区二区 | se综合| 少妇大叫太粗太大爽一区二区 | 色老板精品凹凸在线视频观看 | 好吊操这里只有精品 | 怡春院欧美 | 欧美午夜久久 | 免费av福利 | 一本之道高清无码视频 | 国产成人精品影院 | 97免费在线观看视频 | 一卡二卡国产 | 国产精品久久久午夜夜伦鲁鲁 | 国产学生美女无遮拦高潮视频 | 国产91在线观看丝袜 | 国产精品中文在线 | 日本视频免费在线播放 | 日本免费色视频 | 麻豆久久久久久 | cao久久| 久久av资源网 | 国产大片网站 | 香蕉视频国产 | 美女视频黄是免费 | 青青青国产在线 | 91视频观看| 亚洲乱码国产乱码精品精98午夜 | 叶全真三级| 日韩精品免费看 | 亚洲二区在线视频 | 欧美黑人又粗又大的性格特点 | 中字幕视频在线永久在线观看免费 | 婷婷精品在线 | 亚洲乱码电影 | 麻豆av一区二区三区 | 美女免费黄视频 | 91免费版视频 | 咪咪成人网 | 91色蝌蚪| 国产精品久久久久久久久久久免费看 | 成人伊人| 午夜在线视频免费观看 | 亚洲女人久久久 | 成年人黄色一级片 | 黄色一级片一级片 | 国模无码大尺度一区二区三区 | 猛1被调教成公厕尿便失禁网站 | 91精品人妻一区二区三区果冻 | a级成人毛片 | 少妇做爰k8经典 | 少妇被又大又粗又爽毛片久久黑人 | aaa特级毛片| 亚洲二三区 | 伊人网综合在线 | 色哟哟国产精品色哟哟 | 成人18网站 | 中文字幕无码精品亚洲资源网久久 | 亚洲一级二级片 | 欧美日韩成人一区二区在线观看 | 色综合五月天 | 在线中文字幕一区二区 | 天天天天操 | 三级网站视频 | 琪琪五月天| 亚洲精品乱码久久久久久麻豆不卡 | 无码人妻一区二区三区在线 | 久久久久久久久久成人 | 亚洲青青草 | 黄色国产视频网站 | 国产成人精品一区二区在线小狼 | 亚洲精品一卡二卡 | 精品久久在线观看 |