一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring Cloud 中斷路器 Circuit Breaker 的應用

Spring Cloud 中斷路器 Circuit Breaker 的應用

2021-12-09 22:25Spring源碼解讀 Java教程

SpringCloud Circuit breaker(斷路器)提供了跨不同斷路器實現的抽象。它提供了在應用程序中使用的一致API,允許開發人員選擇最適合應用程序需要的斷路器實現。

Spring Cloud 中斷路器 Circuit Breaker 的應用

環境:Springboot2.3.12.RELEASE +

cloud-netflix-hystrix2.2.10.RELEASE

簡介

SpringCloud Circuit breaker(斷路器)提供了跨不同斷路器實現的抽象。它提供了在應用程序中使用的一致API,允許開發人員選擇最適合應用程序需要的斷路器實現。

支持的斷路器類型:

  • Netfix Hystrix
  • Resilience4J
  • Sentinel
  • Spring Retry

核心概念

要在代碼中創建斷路器(circuit breaker),可以使用斷路器工廠API。當您在類路徑中包含Spring Cloud Circuit Breaker starter時,將自動創建一個實現此API的bean。下面給出了使用此API的一個非常簡單的示例:

  1. @Service
  2. public static class DemoService {
  3. private RestTemplate rest;
  4. private CircuitBreakerFactory cbFactory;
  5. public DemoService(RestTemplate rest, CircuitBreakerFactory cbFactory) {
  6. this.rest = rest;
  7. this.cbFactory = cbFactory;
  8. }
  9. public String slow() {
  10. // 通過默認的CircuitBreakerFactory工廠創建一個指定id(名稱)的斷路器
  11. // run方法是實際執行你的業務方法,第二個參數throwable 是當發生異常或者是執行超時
  12. // 執行的回退(降級)處理
  13. return cbFactory.create("slow").run(() -> rest.getForObject("/slow", String.class), throwable -> "fallback");
  14. }
  15. }

項目配置

通過引入下面不同依賴來確定使用具體的那個斷路器:

  • Hystrix - org.springframework.cloud:spring-cloud-starter-netflix-hystrix
  • Resilience4J - org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j
  • Reactive Resilience4J - org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j
  • Spring Retry - org.springframework.cloud:spring-cloud-starter-circuitbreaker-spring-retry
  • Sentinal - org.springframework.cloud:spring-cloud-starter-circuitbreaker-sentinal

以上5種斷路器是不同的實現方式,根據需要引入即可。

示例

這里以Hystrix為例來使用

引入依賴

  1. org.springframework.cloud
  2. spring-cloud-starter-netflix-hystrix
  3. 2.2.10.RELEASE

定義具有熔斷功能的服務

  1. @Service
  2. public class DemoService {
  3. private RestTemplate rest;
  4. // 注入系統默認的實現
  5. private CircuitBreakerFactory cbFactory;
  6. public DemoService(RestTemplate rest, CircuitBreakerFactory cbFactory) {
  7. this.rest = rest;
  8. this.cbFactory = cbFactory;
  9. }
  10. public String slow() {
  11. // 使用系統默認的實現創建斷路器進行業務的處理
  12. return cbFactory.create("slow").run(() -> rest.getForObject("http://localhost:8080/demos/slow", String.class), throwable -> "fallback");
  13. }
  14. public String slow2() {
  15. // 使用自定義的斷路器工廠進行業務的處理
  16. return cbf().create("demo-slow").run(() -> rest.getForObject("http://localhost:8080/demos/slow", String.class), throwable -> "fallback");
  17. }
  18. // 可以將這個定義為Bean來覆蓋系統默認的實現,在系統默認的實現上有條件限定
  19. private CircuitBreakerFactory cbf() {
  20. HystrixCircuitBreakerFactory cbf = new HystrixCircuitBreakerFactory() ;
  21. // 配置線程池
  22. HystrixThreadPoolProperties.Setter threadPoolProperties = HystrixThreadPoolProperties.Setter() ;
  23. threadPoolProperties.withCoreSize(5)
  24. .withKeepAliveTimeMinutes(5)
  25. .withMaxQueueSize(Integer.MAX_VALUE)
  26. .withQueueSizeRejectionThreshold(1000) ;
  27. // 配置默認的執行行為屬性
  28. HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter() ;
  29. commandProperties.withCircuitBreakerEnabled(true)
  30. // 當請求超過了3s那么斷路器就會工作進行回退(降級處理),執行上面run方法中的第二個參數
  31. .withExecutionTimeoutInMilliseconds(3000)
  32. .withRequestCacheEnabled(true)
  33. // 隔離策略有兩種THREAD,SEMAPHORE
  34. // THREAD: 避免線程被阻塞
  35. // SEMAPHORE: 適合高并發限流處理;因為線程池的方式一般不會創建過多的線程
  36. // 線程是有限的,在高并發情況下是沒法滿足響應處理的。
  37. .withExecutionIsolationStrategy(ExecutionIsolationStrategy.THREAD);
  38. // 將其加入到集合中,為不同的服務創建不同的配置
  39. cbf.configure(builder -> {
  40. builder.commandProperties(commandProperties).groupName("demo") ;
  41. }, "demo-slow");
  42. // 當默認的id不存在時使用這默認的配置
  43. cbf.configureDefault(id -> {
  44. HystrixCommand.Setter setter = HystrixCommand.Setter
  45. .withGroupKey(HystrixCommandGroupKey.Factory.asKey("demo")) // 服務分組,大的模塊
  46. .andCommandKey(HystrixCommandKey.Factory.asKey("demo-slow")) // 服務標識(具體服務分組中的某一個子的服務),子模塊
  47. .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("demo-pools")) // 線程池名稱
  48. .andThreadPoolPropertiesDefaults(threadPoolProperties) // 線程池相關配置
  49. .andCommandPropertiesDefaults(commandProperties) ; // 執行時相關屬性配置
  50. return setter ;
  51. });
  52. return cbf ;
  53. }
  54. }

Controller接口

  1. @RestController
  2. @RequestMapping("/demos")
  3. public class DemoController {
  4. @Resource
  5. private DemoService demoService ;
  6. @GetMapping("/index")
  7. public Object index() {
  8. return demoService.slow2() ;
  9. }
  10. @GetMapping("/slow")
  11. public Object slow() {
  12. try {
  13. TimeUnit.SECONDS.sleep(5) ;
  14. } catch (InterruptedException e) {
  15. e.printStackTrace();
  16. }
  17. return "slow" ;
  18. }
  19. }

原理

CircuitBreakerFactory#create方法創建了CircuitBreaker實例。

根據當前的CLASSPATH我們使用的是Hystrix,那么這里使用的工廠就是:

HystrixCircuitBreakerFactory類

  1. public class HystrixCircuitBreakerFactory extends CircuitBreakerFactory {

泛型參數:Setter就是用來配置Hystrix相關配置信息的(這里主要用來CommandKey與Setter進行綁定),HystrixConfigBuilder用來構建 HystrixCommand.Setter對象。

當執行HystrixCircuitBreakerFactory#configure方法時:

  1. public abstract class AbstractCircuitBreakerFactory> {
  2. private final ConcurrentHashMap configurations = new ConcurrentHashMap<>();
  3. public void configure(Consumer consumer, String... ids) {
  4. for (String id : ids) {
  5. // 構建一個Builder對象
  6. CONFB builder = configBuilder(id);
  7. // 這里通過builder(HystrixConfigBuilder)對象來應用Consumer中編寫的配置信息
  8. consumer.accept(builder);
  9. // 構建HystrixCommand.Setter 對象
  10. CONF conf = builder.build();
  11. // 最后將通過id 與 Setter對象綁定key=value存入Map集合中
  12. getConfigurations().put(id, conf);
  13. }
  14. }
  15. // 該方法在子類HystrixCircuitBreakerFactory中實現
  16. protected abstract CONFB configBuilder(String id);
  17. }

斷路器具體的子類實現

HystrixCircuitBreakerFactory

  1. // 子類繼承的父類中的泛型:第一個泛型參數:需要構建什么樣的一個配置,第二個泛型參數:通過誰來構建第一個泛型參數配置
  2. public class HystrixCircuitBreakerFactory extends CircuitBreakerFactory {
  3. public HystrixConfigBuilder configBuilder(String id) {
  4. return new HystrixConfigBuilder(id);
  5. }
  6. public static class HystrixConfigBuilder extends AbstractHystrixConfigBuilder {
  7. public HystrixConfigBuilder(String id) {
  8. super(id);
  9. }
  10. // 從這里也看出來最終Builder就是用來構建Setter對象用
  11. @Override
  12. public HystrixCommand.Setter build() {
  13. return HystrixCommand.Setter.withGroupKey(getGroupKey())
  14. .andCommandKey(getCommandKey())
  15. .andCommandPropertiesDefaults(getCommandPropertiesSetter());
  16. }
  17. }
  18. }

斷路器工廠有了,接下來就是通過工廠創建具體的斷路器對象了。

通過上面的代碼執行cbf().create("demo-slow")方法時執行了什么?

  1. public class HystrixCircuitBreakerFactory extends CircuitBreakerFactory {
  2. private Function defaultConfiguration = id -> HystrixCommand.Setter
  3. .withGroupKey(HystrixCommandGroupKey.Factory.asKey(getClass().getSimpleName()))
  4. .andCommandKey(HystrixCommandKey.Factory.asKey(id));
  5. public HystrixCircuitBreaker create(String id) {
  6. // 通過上面分析最終所有的Hystrix的Setter會與id綁定存入一個Map中
  7. // 這里computeIfAbsent方法先從集合中通過id獲取,如果獲取不到則將第二個參數存入集合中返回
  8. HystrixCommand.Setter setter = getConfigurations().computeIfAbsent(id, defaultConfiguration);
  9. return new HystrixCircuitBreaker(setter);
  10. }
  11. }

上面創建的是HystrixCircuitBreaker斷路器,當執行run方法時:

  1. public class HystrixCircuitBreaker implements CircuitBreaker {
  2. private HystrixCommand.Setter setter;
  3. public HystrixCircuitBreaker(HystrixCommand.Setter setter) {
  4. this.setter = setter;
  5. }
  6. @Override
  7. public T run(Supplier toRun, Function fallback) {
  8. // 最終執行的就是Hystrix的核心 HystrixCommand對象
  9. HystrixCommand command = new HystrixCommand(setter) {
  10. @Override
  11. protected T run() throws Exception {
  12. return toRun.get();
  13. }
  14. @Override
  15. protected T getFallback() {
  16. return fallback.apply(getExecutionException());
  17. }
  18. };
  19. return command.execute();
  20. }
  21. }

原文鏈接:https://www.toutiao.com/a7036197230167982630/

延伸 · 閱讀

精彩推薦
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
主站蜘蛛池模板: 性欧美videofree中文字幕 | 国产自在线拍 | 亚洲香蕉视频 | 丰满在线观看 | 日韩精品视频在线播放 | 青春草视频免费观看 | 国产精品29页 | 性做久久久久免费观看 | 成人精品亚洲人成在线 | 岛国不卡 | 国产99视频精品免费视频免里 | 欧美一区二区三区四区五区六区 | 白丝vk丨tk失禁 | 美女厕所尿尿擦逼 | 91久久偷偷做嫩草影院免费看 | 欧美日韩国产一区二区三区伦 | 国产亚洲福利精品一区二区 | 美国玩尿眼道videos | 欧美特黄一级大片 | 国产一区二 | 美国美女hd18| 天堂素人在线 | 太大了轻点阿受不了小说h 四色6677最新永久网站 | 国产精品免费 | 欧美骚熟 | 特黄视频| 涩涩成人| 日韩一卡2卡3卡新区网站 | 欧美同志网址 | 久久全国免费久久青青小草 | 我与恶魔的h生活ova | 国精视频一区二区视频 | 日产精品一二三四区国产 | 强迫高h | 北岛玲亚洲一区在线观看 | 侵犯小男生免费视频网站 | 久久精品热99看 | 亚洲小视频网站 | 国内视频一区二区三区 | 青青草精品 | 青苹果乐园影院免费观看完整版 |