自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Spring Cloud 中斷路器 Circuit Breaker 的應(yīng)用

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

[[439483]]

環(huán)境:Springboot2.3.12.RELEASE +

cloud-netflix-hystrix2.2.10.RELEASE

簡介

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

支持的斷路器類型:

  • Netfix Hystrix
  • Resilience4J
  • Sentinel
  • Spring Retry

核心概念

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

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

項目配置

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

  • 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種斷路器是不同的實現(xiàn)方式,根據(jù)需要引入即可。

示例

這里以Hystrix為例來使用

引入依賴

  1. <dependency> 
  2.   <groupId>org.springframework.cloud</groupId> 
  3.   <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> 
  4.   <version>2.2.10.RELEASE</version> 
  5. </dependency> 

定義具有熔斷功能的服務(wù)

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

Controller接口

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

原理

CircuitBreakerFactory#create方法創(chuàng)建了CircuitBreaker實例。

根據(jù)當(dāng)前的CLASSPATH我們使用的是Hystrix,那么這里使用的工廠就是:

HystrixCircuitBreakerFactory類

  1. public class HystrixCircuitBreakerFactory extends CircuitBreakerFactory<HystrixCommand.Setter, HystrixCircuitBreakerFactory.HystrixConfigBuilder> { 

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

當(dāng)執(zhí)行HystrixCircuitBreakerFactory#configure方法時:

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

斷路器具體的子類實現(xiàn)

HystrixCircuitBreakerFactory

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

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

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

  1. public class HystrixCircuitBreakerFactory extends CircuitBreakerFactory<HystrixCommand.Setter, HystrixCircuitBreakerFactory.HystrixConfigBuilder> { 
  2.   private Function<String, HystrixCommand.Setter> 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獲取,如果獲取不到則將第二個參數(shù)存入集合中返回 
  8.     HystrixCommand.Setter setter = getConfigurations().computeIfAbsent(id, defaultConfiguration); 
  9.     return new HystrixCircuitBreaker(setter); 
  10.   } 

 上面創(chuàng)建的是HystrixCircuitBreaker斷路器,當(dāng)執(zhí)行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> T run(Supplier<T> toRun, Function<Throwable, T> fallback) { 
  8.     // 最終執(zhí)行的就是Hystrix的核心 HystrixCommand對象 
  9.     HystrixCommand<T> command = new HystrixCommand<T>(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.   } 

 

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2021-12-15 08:15:26

Spring Circuit BreSpring Clou

2022-10-08 11:39:56

斷路器Golang項目

2022-09-15 15:25:47

spring-微服務(wù)

2023-03-13 08:02:55

斷路器應(yīng)用API

2024-10-06 08:35:44

2023-11-06 08:25:33

項目遠程接口

2017-09-20 09:46:38

Spring BootSpring Clou內(nèi)存

2021-01-14 07:54:19

Spring Clou應(yīng)用路由

2020-07-03 08:00:11

Spring BootSpring Clou流程

2024-04-03 08:58:48

軟件架構(gòu)隔板

2013-05-23 13:31:38

路由器路由器故障路由器故障排除

2021-11-16 11:45:00

SpringSpring ClouJava

2017-12-01 08:54:18

SpringCloudHystrix
點贊
收藏

51CTO技術(shù)棧公眾號