Sentinel的降級熔斷的配置,生産環境使用的時候,一般會在控制台管理,持久化到Nacos;微服務監聽Nacos的配置變化,進而實作服務調用的降級熔斷政策。
寫在前面
用XMind畫了一張導圖記錄Spring Cloud Alibaba的學習筆記(源檔案對部分節點有詳細備注和參考資料,由于太大就沒展示全部,歡迎關注我的公衆号:阿風的架構筆記 背景發送【導圖】拿下載下傳連結, 已經完善更新):
前言
思考這個問題:
Sentinel的降級熔斷的配置,生産環境使用的時候,一般會在控制台管理,持久化到Nacos;微服務監聽Nacos的配置變化,進而實作服務調用的降級熔斷政策。
現在就會遇到這樣的問題,如果有很多Feign接口,如上圖服務A、服務B都有一些Feign接口的遠端調用,都需要我們進行一一配置。而且配置的一些參數絕大多數都一樣的。如:
1、對Feign遠端調用的慢響應政策的配置降級政策
2、對Feign遠端調用的異常數的配置降級政策
3、對Feign遠端調用的異常比例數的配置降級政策
針對上面的配置1-2個服務方法還好;但是現在公司的生産環境都有100~200個微服務,服務之間的調用方法就更多了;那針對普通标準的降級熔斷的配置都需要人工一個個配置,那是不是太麻煩了。
本文就來解決這個問題,跟着繼續往下看。
源碼分析
我們先來看看Sentinel是怎麼設定熔斷政策的,在上圖中我們知道是通過Sentinel控制台進行配置,然後微服務都可以訂閱這些配置;我們看一下源碼。
這個是監聽nacos配置的相關的代碼
上圖代碼核心就是發現配置有變化,就updateValue規則;我們繼續跟蹤代碼發現一個DegradeRuleManager降級規則的管理類,裡面有2個核心的變量ruleMap、circuitBreakers;我們可以猜出就是降級規則集合以及熔斷規則集合。
在繼續往下看,我們發現有個RulePropertyListener中reloadFrom方法****,即重新加載規則;方法裡面有個buildCircuitBreakers方法,一看方法名就知道是建構熔斷政策。
在看一下buildCircuitBreakers方法,我們看到本質就是周遊DegradeRule集合,然後在初始化熔斷對象CircuitBreaker。
這裡我們知道熔斷是怎麼産生的了;本質就是通過DegradeRule産生的。
解決方案
上面我們知道了一些熔斷對象産生的原理,我們隻要可以自定義DegradeRule對象就可以産生。我們在學習Sentinel的時候,他有個Api方式去定義降級規則,大家可以去看一下之前的文章,詳細介紹了Api定義規則的方式。我們看一下案例
我們可以看到DegradeRule對象的定義,以及DegradeRuleManager對象;上面的代碼就能給資源名api定義了慢響應的降級政策了。
講到這裡聰明的小夥伴們有沒有想到一些思路呢?往下看。
方案思路
先給出整體的解決思路
上圖中介紹的流程
1、啟動服務時掃描jar,擷取@FeignClient注解的接口(技術難點一:掃描哪些jar包)
2、獲得Feign接口中的調用方法
3、服務本地建立DegradeRule對象。(技術難點二:Sentinel的資源名支援動态配置)
4、把設定的預設的降級熔斷規則同步到Nacos
根據上面的流程,我們就可以看到,一旦微服務啟動了,就會自動把Feign接口配置預設的降級熔斷規則,以及同步到Nacos中;再結合之前文章中介紹的Sentinel控制台改造,就立刻在控制台顯示這些降級規則了,而不需要認為配置了。
注意:上面隻是介紹了整體流程,在編寫代碼的時候,我們需要考慮到很多場景,如:
一)服務第二次啟動的時候,nacos中已經有了相關的配置,是否還要修改nacos的配置。
二)以及有些特殊業務在Sentinel控制台進行了降級配置,那預設的全局配置如何相容人工的配置。
這些就不在這裡講了,本文隻介紹核心方案思路,核心代碼
其他的有興趣的小夥伴們,可以跟要源碼
技術難點
難點一
我們掃碼jar包,而且是要掃碼包含@FeignClient注解接口的jar。我們知道在使用Feign功能的時候,需要在SpringBootApplication啟動類中加上@EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ApplicationA {
public static void main(String[] args) {
SpringApplication.run(ApplicationA.class, args);
}
}
有的時候Feign包會用第三方jar的形式存在,那代碼就有會變成
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.rainbow.demo1.feign","com.rainbow.demo2.feign"})
public class ApplicationA {
public static void main(String[] args) {
SpringApplication.run(ApplicationA.class, args);
}
}
裡面的@EnableFeignClients注解的屬性basePackages中顯式的指向了Feign包的位置了,這個比較好弄,直接用用ClassScan工具類掃就行了。
ClassScan工具類是支援子包掃描的
那沒有顯式的定義basePackages,那怎麼擷取到jar包路徑呢?
我們可以參考SpringCloud的源碼實作的方法,看代碼。
上面是根據啟動服務時,堆棧資訊擷取main方法的啟動類對象。
根據啟動類對象,擷取到EnableFeignClients對象,如果沒有basePackages,那就是以啟動類的包為掃描的入口。
這樣我們就解決了掃描jar入口的問題。
難點二
正常方式
資源名的擷取,舉個例子
@FeignClient(name = "service-provider")
public interface ProviderServiceFeign {
@GetMapping("/transferHeaders")
public BaseRestResponse<String> transferHeaders();
}
根據微服務的Sentinel資源名定義,@FeignClient(name = "service-provider"),微服務名是service-provider;那針對transferHeaders()方法的降級政策資源名即為
lb://service-provider/transferHeaders
這個實作比較簡單就是擷取@FeignClient的name的值,以及方法@GetMapping裡面的值就可以拼接出資源名。
指定Url位址
@FeignClient(name = "service-provider",url = "http://xxxxx")
public interface ProviderServiceFeign {
@GetMapping("/transferHeaders")
public BaseRestResponse<String> transferHeaders();
}
指定url的目的其實就是指定請求的方式,這種情況的Sentinel的資源名即為
http://xxxxx/transferHeaders
這個技術實作也比較簡單,隻需要考慮到這個場景,就可以了。
動态配置Url
還有一種情況即對接第三方平台時,我們一般不會寫死Url,而是通過配置的方式,如
@FeignClient(name = "service-provider",url = "${reqUrl}")
public interface ProviderServiceFeign {
@GetMapping("/transferHeaders")
public BaseRestResponse<String> transferHeaders();
}
上面的${reqUrl}是通過配置的,那Sentinel的資源名是什麼樣的呢?本質上面資源名也是Url+具體的請求位址,即
http://${reqUrl}/transferHeaders
但是這樣設定資源名肯定是不正确的,需要把具體的配置值拿過來拼接。那我們就需要在程式中擷取${reqUrl}的值,講到這裡小夥伴們知道怎麼實作了嗎?其實就是用到
Environment environment ;//環境變量對象
this.environment.resolvePlaceholders(url);//擷取變量的值
核心代碼
上面的技術難點解決掉之後,我們就放開雙手撸代碼了,這裡貼上核心的代碼;小夥伴們。
public class DegradeRuleInitializer implements ApplicationRunner, EnvironmentAware
實作ApplicationRunner, EnvironmentAware就能夠實作啟動時,去掃描了,入口就在ApplicationRunner中的run方法。
掃描類
掃描FeignClient
初始化預設規則
設定了預設降級規則,把配置資訊釋出到nacos
效果
一旦微服務啟動了,nacos配置就有了
我們會把預設的值釋出到nacos裡面,小夥伴們可以具體看一些資源名,裡面就會有很多降級規則。
我們再來看看Sentinel控制台,裡面就顯示了降級規則清單;設計的是針對同一個資源名做異常數、異常比例、慢響應三種類型的降級熔斷政策。
全局預設的值,到底是多少閥值,是可以通過配置的方式的,這些就不介紹了。比較簡單。
到這裡就全部實作了微服務中Feign接口的降級熔斷政策的預設化配置,不需要人工去添加了;當然是支援人工去修改的,如果需要修改閥值,可以人工修改。
總結
本文介紹了Sentinel的全局Feign預設熔斷的技術實作方案,整體思路原理不是太複雜,就是利用其本身的功能,做了一些擴充;這樣更友善使用者的使用。
看完三件事❤️
如果你覺得這篇内容對你還蠻有幫助,我想邀請你幫我三個小忙:
- 點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
- 關注公衆号 『 阿風的架構筆記 』,不定期分享原創知識。
- 同時可以期待後續文章ing