SpringCloud中断路器CircuitBreaker的
环境:Springboot2。3。12。RELEASEcloudnetflixhystrix2。2。10。RELEASE简介
SpringCloudCircuitbreaker(断路器)提供了跨不同断路器实现的抽象。它提供了在应用程序中使用的一致API,允许开发人员选择最适合应用程序需要的断路器实现。
支持的断路器类型:NetfixHystrixResilience4JSentinelSpringRetry核心概念
要在代码中创建断路器(circuitbreaker),可以使用断路器工厂API。当您在类路径中包含SpringCloudCircuitBreakerstarter时,将自动创建一个实现此API的bean。下面给出了使用此API的一个非常简单的示例:ServicepublicstaticclassDemoService{privateRestTemplaterest;privateCircuitBreakerFactorycbFactory;publicDemoService(RestTemplaterest,CircuitBreakerFactorycbFactory){this。restrest;this。cbFactorycbFactory;}publicStringslow(){通过默认的CircuitBreakerFactory工厂创建一个指定id(名称)的断路器run方法是实际执行你的业务方法,第二个参数throwable是当发生异常或者是执行超时执行的回退(降级)处理returncbFactory。create(slow)。run(()rest。getForObject(slow,String。class),throwablefallback);}}项目配置
通过引入下面不同依赖来确定使用具体的那个断路器Hystrixorg。springframework。cloud:springcloudstarternetflixhystrixResilience4Jorg。springframework。cloud:springcloudstartercircuitbreakerresilience4jReactiveResilience4Jorg。springframework。cloud:springcloudstartercircuitbreakerreactorresilience4jSpringRetryorg。springframework。cloud:springcloudstartercircuitbreakerspringretrySentinalorg。springframework。cloud:springcloudstartercircuitbreakersentinal
以上5种断路器是不同的实现方式,根据需要引入即可。示例
这里以Hystrix为例来使用
引入依赖dependencygroupIdorg。springframework。cloudgroupIdspringcloudstarternetflixhystrixartifactIdversion2。2。10。RELEASEversiondependency
定义具有熔断功能的服务ServicepublicclassDemoService{privateRestTemplaterest;注入系统默认的实现privateCircuitBreakerFactorycbFactory;publicDemoService(RestTemplaterest,CircuitBreakerFactorycbFactory){this。restrest;this。cbFactorycbFactory;}publicStringslow(){使用系统默认的实现创建断路器进行业务的处理returncbFactory。create(slow)。run(()rest。getForObject(http:localhost:8080demosslow,String。class),throwablefallback);}publicStringslow2(){使用自定义的断路器工厂进行业务的处理returncbf()。create(demoslow)。run(()rest。getForObject(http:localhost:8080demosslow,String。class),throwablefallback);}可以将这个定义为Bean来覆盖系统默认的实现,在系统默认的实现上有条件限定privateCircuitBreakerFactoryHystrixCommand。Setter,HystrixCircuitBreakerFactory。HystrixConfigBuildercbf(){HystrixCircuitBreakerFactorycbfnewHystrixCircuitBreakerFactory();配置线程池HystrixThreadPoolProperties。SetterthreadPoolPropertiesHystrixThreadPoolProperties。Setter();threadPoolProperties。withCoreSize(5)。withKeepAliveTimeMinutes(5)。withMaxQueueSize(Integer。MAXVALUE)。withQueueSizeRejectionThreshold(1000);配置默认的执行行为属性HystrixCommandProperties。SettercommandPropertiesHystrixCommandProperties。Setter();commandProperties。withCircuitBreakerEnabled(true)当请求超过了3s那么断路器就会工作进行回退(降级处理),执行上面run方法中的第二个参数。withExecutionTimeoutInMilliseconds(3000)。withRequestCacheEnabled(true)隔离策略有两种THREAD,SEMAPHORETHREAD:避免线程被阻塞SEMAPHORE:适合高并发限流处理;因为线程池的方式一般不会创建过多的线程线程是有限的,在高并发情况下是没法满足响应处理的。。withExecutionIsolationStrategy(ExecutionIsolationStrategy。THREAD);将其加入到集合中,为不同的服务创建不同的配置cbf。configure(builder{builder。commandProperties(commandProperties)。groupName(demo);},demoslow);当默认的id不存在时使用这默认的配置cbf。configureDefault(id{HystrixCommand。SettersetterHystrixCommand。Setter。withGroupKey(HystrixCommandGroupKey。Factory。asKey(demo))服务分组,大的模块。andCommandKey(HystrixCommandKey。Factory。asKey(demoslow))服务标识(具体服务分组中的某一个子的服务),子模块。andThreadPoolKey(HystrixThreadPoolKey。Factory。asKey(demopools))线程池名称。andThreadPoolPropertiesDefaults(threadPoolProperties)线程池相关配置。andCommandPropertiesDefaults(commandProperties);执行时相关属性配置returnsetter;});returncbf;}}
Controller接口RestControllerRequestMapping(demos)publicclassDemoController{ResourceprivateDemoServicedemoService;GetMapping(index)publicObjectindex(){returndemoService。slow2();}GetMapping(slow)publicObjectslow(){try{TimeUnit。SECONDS。sleep(5);}catch(InterruptedExceptione){e。printStackTrace();}returnslow;}}原理
CircuitBreakerFactorycreate方法创建了CircuitBreaker实例
根据当前的CLASSPATH我们使用的是Hystrix,那么这里使用的工厂就是:
HystrixCircuitBreakerFactory类publicclassHystrixCircuitBreakerFactoryextendsCircuitBreakerFactoryHystrixCommand。Setter,HystrixCircuitBreakerFactory。HystrixConfigBuilder{
泛型参数:Setter就是用来配置Hystrix相关配置信息的(这里主要用来CommandKey与Setter进行绑定),HystrixConfigBuilder用来构建HystrixCommand。Setter对象。
当执行HystrixCircuitBreakerFactoryconfigure方法时:publicabstractclassAbstractCircuitBreakerFactoryCONF,CONFBextendsConfigBuilderCONF{privatefinalConcurrentHashMapString,CONFconfigurationsnewConcurrentHashMap();publicvoidconfigure(ConsumerCONFBconsumer,String。。。ids){for(Stringid:ids){构建一个Builder对象CONFBbuilderconfigBuilder(id);这里通过builder(HystrixConfigBuilder)对象来应用Consumer中编写的配置信息consumer。accept(builder);构建HystrixCommand。Setter对象CONFconfbuilder。build();最后将通过id与Setter对象绑定keyvalue存入Map集合中getConfigurations()。put(id,conf);}}该方法在子类HystrixCircuitBreakerFactory中实现protectedabstractCONFBconfigBuilder(Stringid);}
断路器具体的子类实现HystrixCircuitBreakerFactory子类继承的父类中的泛型:第一个泛型参数:需要构建什么样的一个配置,第二个泛型参数:通过谁来构建第一个泛型参数配置publicclassHystrixCircuitBreakerFactoryextendsCircuitBreakerFactoryHystrixCommand。Setter,HystrixCircuitBreakerFactory。HystrixConfigBuilder{publicHystrixConfigBuilderconfigBuilder(Stringid){returnnewHystrixConfigBuilder(id);}publicstaticclassHystrixConfigBuilderextendsAbstractHystrixConfigBuilderHystrixCommand。Setter{publicHystrixConfigBuilder(Stringid){super(id);}从这里也看出来最终Builder就是用来构建Setter对象用OverridepublicHystrixCommand。Setterbuild(){returnHystrixCommand。Setter。withGroupKey(getGroupKey())。andCommandKey(getCommandKey())。andCommandPropertiesDefaults(getCommandPropertiesSetter());}}}
断路器工厂有了,接下来就是通过工厂创建具体的断路器对象了
通过上面的代码执行cbf()。create(demoslow)方法时执行了什么?publicclassHystrixCircuitBreakerFactoryextendsCircuitBreakerFactoryHystrixCommand。Setter,HystrixCircuitBreakerFactory。HystrixConfigBuilder{privateFunctionString,HystrixCommand。SetterdefaultConfigurationidHystrixCommand。Setter。withGroupKey(HystrixCommandGroupKey。Factory。asKey(getClass()。getSimpleName()))。andCommandKey(HystrixCommandKey。Factory。asKey(id));publicHystrixCircuitBreakercreate(Stringid){通过上面分析最终所有的Hystrix的Setter会与id绑定存入一个Map中这里computeIfAbsent方法先从集合中通过id获取,如果获取不到则将第二个参数存入集合中返回HystrixCommand。SettersettergetConfigurations()。computeIfAbsent(id,defaultConfiguration);returnnewHystrixCircuitBreaker(setter);}}
上面创建的是HystrixCircuitBreaker断路器,当执行run方法时:publicclassHystrixCircuitBreakerimplementsCircuitBreaker{privateHystrixCommand。Settersetter;publicHystrixCircuitBreaker(HystrixCommand。Settersetter){this。settersetter;}OverridepublicTTrun(SupplierTtoRun,FunctionThrowable,Tfallback){最终执行的就是Hystrix的核心HystrixCommand对象HystrixCommandTcommandnewHystrixCommandT(setter){OverrideprotectedTrun()throwsException{returntoRun。get();}OverrideprotectedTgetFallback(){returnfallback。apply(getExecutionException());}};returncommand。execute();}}
完毕!!!
关注转发
Sentinel与Hystrix的对比
SpringCloudHystrix实现资源隔离应用
SpringCloudGateway应用Hystrix限流功能自定义Filter详解
SpringBootSecurity防重登录及在线总数
SpringRetry重试框架的应用
springbootmybatisjpa实现读写分离
Spring容器对象BeanFactory与ApplicationContext你都清楚了吗?