Hystrix配置實戰及feign超時配置失效


一、feign超時配置失效

最近項目上遇見feign超時配置總是失效。導致feign調用超過2s之后就會超時,會進行自動重試,重復調用兩次服務,並且還是指定接口。這就更加奇怪。最后通過觀察以及源碼調試,發現問題所在。在這里先說下原因。

 

原因:同一個服務feign組件做了拆分,使用contextId對feign拆分后的feign做了聲明。配置超時配置的時候,不能再使用feign組件注解 @FeignClient里的name去做配置了,而應該是contextId里的名稱

示例代碼:

//A服務的基礎業務接口
@FeignClient(contextId = "AServer", name = "AServer", configuration = FeignConfiguration.class)
public interface ABaseServer {

}

//A服務的個性化業務接口
@FeignClient(contextId = "ASpecialServiceServer", name = "AServer", configuration = FeignConfiguration.class)
public interface ASpecialServer {

}

//上面是對feign拆分后的聲明
//錯誤的yml配置
feign:
  client:
    config:
#這里仍然使用了name作為超時配置,那么只有ABaseServer 里面聲明的接口才會使用以下的配置,因為恰巧ABaseServer的contextId名稱是AServer。
      AServer: 
        connectTimeout: 60000
        readTimeout: 60000

//正確的yml配置,手段一:配置上以contextId為聲明來配置
feign:
  client:
    config:
#基礎業務接口的超時配置
      AServer: 
        connectTimeout: 60000
        readTimeout: 60000
#個性化業務接口的超時配置
      ASpecialServiceServer: 
        connectTimeout: 50000
        readTimeout: 50000

//正確的yml配置,手段二:A服務全部使用default全局配置,Bserver單獨聲明,並不會使用全局配置
feign:
  client:
    config:
      default: 
        connectTimeout: 60000
        readTimeout: 60000
      BServer:
        connectTimeout: 30000
        readTimeout: 30000

 

feign內部集成了ribbon做為了負載均衡的組件,ribbon也有相關超時配置,feign的超時配置不當也會造成超時失效,關於如何配置可以參考之前的一篇博客:https://www.cnblogs.com/wa1l-E/p/13994240.html

這次feign的超時不生效,主要原因是,項目上做了一次feign的拆分,即A服務調用B服務的接口由於過多,接口從功能模塊和業務上做了feign組件的拆分,也就是spring容器中會有兩個feign針對同一個服務。

問題1:拆分后,springboot在啟動時,會報錯,原因是針對同一個服務有多個feign 實例,而spring容器又默認是單例加載。

解決這個問題有兩個方案:

1、

 

2、在feign注解定義上加上contextId來避免啟動報錯。示例代碼如下:

@FeignClient(name = "A", contextId = "ABaseServiceServer", configuration = FeignConfiguration.class)
public interface AServer {

}


@FeignClient(name = "A", contextId = "ACustomServiceServer", configuration = FeignConfiguration.class)
public interface AServer {

}

都是同一個服務的feign組件,但是contextId不同,解決了問題。

項目上采用了第二種解決手段,但也正是因為對解決問題沒有做到追根刨底的精神,導致引入了feign超時失效的原因。

問題2:使用ContextId對feign做聲明后,導致部分接口超時失效。

結論:在開篇時,結論已經說過,這里就不再贅述。主要說下原因以及定位問題的過程和解決方法。

定位過程:發現該問題時,首先發現是部分接口失效,當然是測試並觀察,發現只有未使用contextId配置的feign組件的接口會超時。但是當時並不知道是contextId的聲明影響。所以果斷開撕源碼。定位問題

首先Feign有一個內部類Builder,聽名字就知道使用了建造者是設計模式,建造者適合創造屬性多變的對象, 而Feign恰好具備這種特性,使用建造者設計模式在適合不過了。

Builder類有一個屬性Options option這個Options類就是feign的超時配置聲明。如下圖:

 

 

 

    再來看一下UML圖

 

 

 

     可以看到真正的配置就是再容器初始話feign的時候,初始化 builder的時候使用的配置就是真正使用的配置。那么接下來就好辦了,使用我之前講過的源碼調試大法,開始調試,啟動服務,斷點開啟,最后一路追蹤,發現實例化的代碼如下:

     不知道啟動后怎么調試找到相關代碼的同學可以參考另一篇博客:https://www.cnblogs.com/wa1l-E/p/14115042.html    還是一句話,動手多實踐。

    

 

 

    97行見名其義:初始化Feign.builder,109行是關鍵代碼,看名字就知道,配置feign,那么builder的option一定是在這里初始化的,我們一路追進去看看

 

 

到了上面的方法中,我們發現了尤其重要的兩行代碼,看名字就知道使用configure配置屬性,那么在這里一定是使用配置去初始話Feign的超時相關配置,沒有的話會使用默認的配置。
這里的方法就不贅述了,有興趣的同學可以去斷點看看,最關鍵的另一個發現是 在獲取配置的時候,使用的是
contextId,這不由得和上面Feign注解 @FeignClient中聲明的contextId關聯起來,最后通過調試也發現,確實是這樣。contextId源碼注釋是bean的顯實聲明名稱,如果不配置默認使用beanName.到這里就發現問題了。
那么解決手段就簡單了

解決手段:

手段一:如果拆分后的接口不需要做特殊的超時配置區分,那么使用default全局配置既可,至於其他的feign客戶端,在做配置,便不會使用全局的配置。

手段二:如果拆分后的接口,超時配置是不一樣的,那么使用contextId做超時配置才是正確的。

最后建議實際使用手段二,粒度更細。

 

二、Hystrix配置實戰:

首先介紹一下上面Feign超時后,Hystrix配置后,會自動重試的原因,然后再介紹一下Hystrix的主要配置,搭建一個Hstrix-dashboard,然后通過一個接口的測試,通過dashBoard觀察Hystrix的配置的。

 1、Hystrix的配置

熔斷配置:

#hystrix熔斷器配置:(接口發生異常,服務調用方直接做熔斷處理,返回提示,避免流量過大接口調用引起雪崩。)

#如果接口發生異常,那么會熔斷,熔斷開啟。后面的請求不會再去進行服務遠程調用,直接走熔斷 #下面配置策略是: 10s滾動窗口期內,大於等於1個線程 失敗率超過百分之50,則打開熔斷開關.負責關閉熔斷開關 #熔斷開關打開后,后續請求直接走熔斷,不會進行遠程調用 hystrix.command.
default.circuitBreaker.requestVolumeThreshold=1 hystrix.command.default.metrics.rollingStats.timeInMilliseconds=10000 hystrix.command.default.circuitBreaker.errorThresholdPercentage=50 #在5s后,熔斷會進入 半開狀態,會放入一部分請求進行遠程調用,如果成功,則關閉熔斷.如果失敗,則繼續打開熔斷 hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=5000

降級配置:

#hystrix降級配置:(接口發生異常,服務調用方直接對接口進行降級處理,返回托底數據。和熔斷的區別是一個有托底數據,一個沒有。)
#超時打開,設置為70s,這里的超時時間必須大於Ribbon和feign的超時,因為小於Feign正常調用超時時間,直接會熔斷. hystrix.command.
default.execution.timeout.enabled=true hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=70000

 2、配置Hystrix-dashboard調試Hystrix熔斷和降級配置

  • 搭建Hystrix-dashboard: 沒空的同學可以直接下載我之前搭建的: https://github.com/coffeebabeCGG/spring-cloud 這里就不贅述如何搭建了
  • 啟動項目后,需要填如要監控的服務地址:http://ip:port/context-path/actuator/hystrix.stream
  •  

     


  • 從下圖可以看到queryByPage接口的熔斷目前是關閉狀態。關於dashboard的詳細參數說明,下面給大家補一張圖。

     

     

     

 

 

最后:接口postMan的runtest批量調用接口測試,通過dashBoard觀察接口的熔斷情況,配置是否生效。就可以了解Hystrix的基本使用了。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM