国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - 詳解feign調(diào)用session丟失解決方案

詳解feign調(diào)用session丟失解決方案

2021-07-16 15:00zl1zl2zl3 Java教程

這篇文章主要介紹了詳解feign調(diào)用session丟失解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

最近在做項(xiàng)目的時(shí)候發(fā)現(xiàn),微服務(wù)使用feign相互之間調(diào)用時(shí),存在session丟失的問(wèn)題。例如,使用feign調(diào)用某個(gè)遠(yuǎn)程api,這個(gè)遠(yuǎn)程api需要傳遞一個(gè)鑒權(quán)信息,我們可以把cookie里面的session信息放到header里面,這個(gè)header是動(dòng)態(tài)的,跟你的httprequest相關(guān),我們選擇編寫(xiě)一個(gè)攔截器來(lái)實(shí)現(xiàn)header的傳遞,也就是需要實(shí)現(xiàn)requestinterceptor接口,具體代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@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);
    }
   }
  }
 
 }
 
}

經(jīng)過(guò)測(cè)試,上面的解決方案可以正常的使用; 

但是,當(dāng)引入hystrix熔斷策略時(shí),出現(xiàn)了一個(gè)新的問(wèn)題:

?
1
requestattributes requestattributes = requestcontextholder.getrequestattributes();

此時(shí)requestattributes會(huì)返回null,從而無(wú)法傳遞session信息,最終發(fā)現(xiàn)requestcontextholder.getrequestattributes(),該方法是從threadlocal變量里面取得對(duì)應(yīng)信息的,這就找到問(wèn)題原因了,是由于hystrix熔斷機(jī)制導(dǎo)致的。 
hystrix有2個(gè)隔離策略:thread以及semaphore,當(dāng)隔離策略為 thread 時(shí),是沒(méi)辦法拿到 threadlocal 中的值的。

因此有兩種解決方案:

方案一:調(diào)整格隔離策略:

?
1
hystrix.command.default.execution.isolation.strategy: semaphore

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

但該方案不是特別好。原因是hystrix官方強(qiáng)烈建議使用thread作為隔離策略! 可以參考官方文檔說(shuō)明。

方案二:自定義策略

記得之前在研究zipkin日志追蹤的時(shí)候,看到過(guò)sleuth有自己的熔斷機(jī)制,用來(lái)在thread之間傳遞trace信息,sleuth是可以拿到自己上下文信息的,查看源碼找到了 
org.springframework.cloud.sleuth.instrument.hystrix.sleuthhystrixconcurrencystrategy 
這個(gè)類,查看sleuthhystrixconcurrencystrategy的源碼,繼承了hystrixconcurrencystrategy,用來(lái)實(shí)現(xiàn)了自己的并發(fā)策略。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * 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" rel="external nofollow" >https://github.com/netflix/hystrix/wiki/plugins</a>.
 */
public abstract class hystrixconcurrencystrategy

搜索發(fā)現(xiàn)有好幾個(gè)地方繼承了hystrixconcurrencystrategy類 

詳解feign調(diào)用session丟失解決方案

其中就有我們熟悉的spring security和剛才提到的sleuth都是使用了自定義的策略,同時(shí)由于hystrix只允許有一個(gè)并發(fā)策略,因此為了不影響spring security和sleuth,我們可以參考他們的策略實(shí)現(xiàn)自己的策略,大致思路: 

將現(xiàn)有的并發(fā)策略作為新并發(fā)策略的成員變量; 

在新并發(fā)策略中,返回現(xiàn)有并發(fā)策略的線程池、queue; 

代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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();
   }
  }
 }
}

最后,將這個(gè)策略類作為bean配置到feign的配置類feignclientsconfigurationcustom中

?
1
2
3
4
@bean
public feignhystrixconcurrencystrategy feignhystrixconcurrencystrategy() {
 return new feignhystrixconcurrencystrategy();
}

至此,結(jié)合feignclientsconfigurationcustom配置feign調(diào)用session丟失的問(wèn)題完美解決。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。 

原文鏈接:https://blog.csdn.net/zl1zl2zl3/article/details/79084368

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91精品久久久久久久久久 | 欧美日韩视频 | 欧美精品久久久久久久久老牛影院 | 亚洲理论电影在线观看 | 国产精品精品 | 激情久久网 | 久久久高清 | 日韩黄网 | 99久久精品国产毛片 | 91精品国产综合久久久久久 | 91欧美激情一区二区三区成人 | 国产在线a| 毛片在线网址 | 久久与欧美| 国产精品中文字幕在线观看 | 黄色a级 | 午夜免费电影 | 黄视频免费观看 | 日韩欧美在线观看 | 成人日韩视频在线观看 | 欧美精品在线一区 | 国产免费高清 | 午夜免费福利影院 | 亚洲视频三区 | 日韩在线播放一区 | 国产精品视频一区二区三区不卡 | 亚洲一区中文字幕 | 亚洲天堂中文 | 欧美jjzz| 好看的国产精彩视频 | 91性高湖久久久久久久久网站 | 久久久久久网站 | 国产精品18久久久久vr手机版特色 | 无码一区二区三区视频 | 99国产视频 | 午夜伦4480yy私人影院 | 精品综合| 成年人在线观看 | 国产va在线 | 久久久国产精品 | 日韩在线观看中文字幕 |