SpringCloud中断路器CircuitBreaker的应用
环境: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的一个非常简单的示例:@Service public static class DemoService { private RestTemplate rest; private CircuitBreakerFactory cbFactory; public DemoService(RestTemplate rest, CircuitBreakerFactory cbFactory) { this.rest = rest; this.cbFactory = cbFactory; } public String slow() { // 通过默认的CircuitBreakerFactory工厂创建一个指定id(名称)的断路器 // run方法是实际执行你的业务方法,第二个参数throwable 是当发生异常或者是执行超时 // 执行的回退(降级)处理 return cbFactory.create("slow").run(() -> rest.getForObject("/slow", String.class), throwable -> "fallback"); } }项目配置
通过引入下面不同依赖来确定使用具体的那个断路器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为例来使用
引入依赖 org.springframework.cloud spring-cloud-starter-netflix-hystrix 2.2.10.RELEASE
定义具有熔断功能的服务@Service public class DemoService { private RestTemplate rest; // 注入系统默认的实现 private CircuitBreakerFactory cbFactory; public DemoService(RestTemplate rest, CircuitBreakerFactory cbFactory) { this.rest = rest; this.cbFactory = cbFactory; } public String slow() { // 使用系统默认的实现创建断路器进行业务的处理 return cbFactory.create("slow").run(() -> rest.getForObject("http://localhost:8080/demos/slow", String.class), throwable -> "fallback"); } public String slow2() { // 使用自定义的断路器工厂进行业务的处理 return cbf().create("demo-slow").run(() -> rest.getForObject("http://localhost:8080/demos/slow", String.class), throwable -> "fallback"); } // 可以将这个定义为Bean来覆盖系统默认的实现,在系统默认的实现上有条件限定 private CircuitBreakerFactory cbf() { HystrixCircuitBreakerFactory cbf = new HystrixCircuitBreakerFactory() ; // 配置线程池 HystrixThreadPoolProperties.Setter threadPoolProperties = HystrixThreadPoolProperties.Setter() ; threadPoolProperties.withCoreSize(5) .withKeepAliveTimeMinutes(5) .withMaxQueueSize(Integer.MAX_VALUE) .withQueueSizeRejectionThreshold(1000) ; // 配置默认的执行行为属性 HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter() ; commandProperties.withCircuitBreakerEnabled(true) // 当请求超过了3s那么断路器就会工作进行回退(降级处理),执行上面run方法中的第二个参数 .withExecutionTimeoutInMilliseconds(3000) .withRequestCacheEnabled(true) // 隔离策略有两种THREAD,SEMAPHORE // THREAD: 避免线程被阻塞 // SEMAPHORE: 适合高并发限流处理;因为线程池的方式一般不会创建过多的线程 // 线程是有限的,在高并发情况下是没法满足响应处理的。 .withExecutionIsolationStrategy(ExecutionIsolationStrategy.THREAD); // 将其加入到集合中,为不同的服务创建不同的配置 cbf.configure(builder -> { builder.commandProperties(commandProperties).groupName("demo") ; }, "demo-slow"); // 当默认的id不存在时使用这默认的配置 cbf.configureDefault(id -> { HystrixCommand.Setter setter = HystrixCommand.Setter .withGroupKey(HystrixCommandGroupKey.Factory.asKey("demo")) // 服务分组,大的模块 .andCommandKey(HystrixCommandKey.Factory.asKey("demo-slow")) // 服务标识(具体服务分组中的某一个子的服务),子模块 .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("demo-pools")) // 线程池名称 .andThreadPoolPropertiesDefaults(threadPoolProperties) // 线程池相关配置 .andCommandPropertiesDefaults(commandProperties) ; // 执行时相关属性配置 return setter ; }); return cbf ; } }
Controller接口@RestController @RequestMapping("/demos") public class DemoController { @Resource private DemoService demoService ; @GetMapping("/index") public Object index() { return demoService.slow2() ; } @GetMapping("/slow") public Object slow() { try { TimeUnit.SECONDS.sleep(5) ; } catch (InterruptedException e) { e.printStackTrace(); } return "slow" ; } }原理
CircuitBreakerFactory#create方法创建了CircuitBreaker实例
根据当前的CLASSPATH我们使用的是Hystrix,那么这里使用的工厂就是:
HystrixCircuitBreakerFactory类public class HystrixCircuitBreakerFactory extends CircuitBreakerFactory {
泛型参数:Setter就是用来配置Hystrix相关配置信息的(这里主要用来CommandKey与Setter进行绑定),HystrixConfigBuilder用来构建 HystrixCommand.Setter对象。
当执行HystrixCircuitBreakerFactory#configure方法时:public abstract class AbstractCircuitBreakerFactory> { private final ConcurrentHashMap configurations = new ConcurrentHashMap<>(); public void configure(Consumer consumer, String... ids) { for (String id : ids) { // 构建一个Builder对象 CONFB builder = configBuilder(id); // 这里通过builder(HystrixConfigBuilder)对象来应用Consumer中编写的配置信息 consumer.accept(builder); // 构建HystrixCommand.Setter 对象 CONF conf = builder.build(); // 最后将通过id 与 Setter对象绑定key=value存入Map集合中 getConfigurations().put(id, conf); } } // 该方法在子类HystrixCircuitBreakerFactory中实现 protected abstract CONFB configBuilder(String id); }
断路器具体的子类实现HystrixCircuitBreakerFactory// 子类继承的父类中的泛型:第一个泛型参数:需要构建什么样的一个配置,第二个泛型参数:通过谁来构建第一个泛型参数配置 public class HystrixCircuitBreakerFactory extends CircuitBreakerFactory { public HystrixConfigBuilder configBuilder(String id) { return new HystrixConfigBuilder(id); } public static class HystrixConfigBuilder extends AbstractHystrixConfigBuilder { public HystrixConfigBuilder(String id) { super(id); } // 从这里也看出来最终Builder就是用来构建Setter对象用 @Override public HystrixCommand.Setter build() { return HystrixCommand.Setter.withGroupKey(getGroupKey()) .andCommandKey(getCommandKey()) .andCommandPropertiesDefaults(getCommandPropertiesSetter()); } } }
断路器工厂有了,接下来就是通过工厂创建具体的断路器对象了
通过上面的代码执行cbf().create("demo-slow")方法时执行了什么?public class HystrixCircuitBreakerFactory extends CircuitBreakerFactory { private Function defaultConfiguration = id -> HystrixCommand.Setter .withGroupKey(HystrixCommandGroupKey.Factory.asKey(getClass().getSimpleName())) .andCommandKey(HystrixCommandKey.Factory.asKey(id)); public HystrixCircuitBreaker create(String id) { // 通过上面分析最终所有的Hystrix的Setter会与id绑定存入一个Map中 // 这里computeIfAbsent方法先从集合中通过id获取,如果获取不到则将第二个参数存入集合中返回 HystrixCommand.Setter setter = getConfigurations().computeIfAbsent(id, defaultConfiguration); return new HystrixCircuitBreaker(setter); } }
上面创建的是HystrixCircuitBreaker断路器,当执行run方法时:public class HystrixCircuitBreaker implements CircuitBreaker { private HystrixCommand.Setter setter; public HystrixCircuitBreaker(HystrixCommand.Setter setter) { this.setter = setter; } @Override public T run(Supplier toRun, Function fallback) { // 最终执行的就是Hystrix的核心 HystrixCommand对象 HystrixCommand command = new HystrixCommand(setter) { @Override protected T run() throws Exception { return toRun.get(); } @Override protected T getFallback() { return fallback.apply(getExecutionException()); } }; return command.execute(); } }
完毕!!!
关注+转发
Sentinel 与 Hystrix 的对比
SpringCloud Hystrix实现资源隔离应用
SpringCloud Gateway 应用Hystrix 限流功能 自定义Filter详解
Spring Boot Security防重登录及在线总数
Spring Retry重试框架的应用
springboot mybatis jpa 实现读写分离
Spring容器对象BeanFactory与ApplicationContext你都清楚了吗?
小山村何以惊艳大世界河南安阳市,游客在红旗渠畔的庙荒村中散步。新华社发游客在浙江杭州市临安区太湖源镇指南村观赏晒秋的农作物。新华社发重庆酉阳县板溪镇叠石花谷景区内,游客在粉黛乱子草组成的粉色花海中游玩
男篮4黑马入选世界杯,同曦天才却遗憾落选,郭艾伦也有接班人了男篮39人世界杯名单出炉,顶尖的1米85后卫,加上2米18的中锋重磅入选。然而南京非常优秀的1米91天才,却尴尬地落选了。对于姚明跟乔尔杰维奇,新一套的选人标准,确实在大赛当中受到
澳网首轮爆大冷!8号种子遭世界第98淘汰,54分钟速败仅得2局北京时间1月18日,澳网进入第3比赛日的争夺。在女单第1轮延期的一场比赛当中,赛会8号种子卡萨金娜同世界排名98位的格拉切娃相遇。经过了两盘比赛的较量,卡萨金娜02速败出局,止步今
乒坛大爆冷!3位世界冠军一轮游,国乒8人被淘汰,多位名将输球北京时间1月19日凌晨,乒乓球WTT卡塔尔赛结束了首个正赛日的较量,当天就有3位世界冠军在单打项目中一轮游出局,分别是庄智渊倪夏莲法尔克,而国乒单打目前已经有8人被淘汰,双打也折损
国际锐评丨中国仍然是世界上最大的增长故事中国国家统计局17日发布了2022年国民经济数据据初步核算,去年中国国内生产总值达1210207亿元,按不变价格计算,比上年增长3。0。这是继2020年2021年连续突破100万亿
省政协委员袁斌才祁连山国家公园具有打造世界级旅游目的地的潜质本网记者宋芳科任磊沈文刚省政协委员民革甘肃省委会专职副主委袁斌才认为,祁连山国家公园生态地位重要自然景观独特科学研究和生态旅游价值极高。随着国家公园未来的正式批准设立,其国家代表性
中国新国门全面复航拥抱世界1月17日,从北京大兴飞往香港的南航CZ309次出境航班起飞。新华社记者鞠焕宗摄新华社北京1月18日电题中国新国门全面复航拥抱世界新华社记者罗鑫吉宁作为中国新国门,北京大兴国际机场
肇庆法院一案一策为企业带来稳稳安全感活力湾区法治护航活力湾区法治护航肇庆,作为粤港澳大湾区重要节点城市,具有独特的区位交通生态环境历史文化土地空间产业基础等优势,先后有宁德时代山鹰国际国信通等企业入驻。早在2017年5月,某新能源公
如果努力没有结果,那就先停下来你有没有问过这样的问题如果付出了努力,却依旧没有收获怎么办?比如认真做了复习,依旧考不出一个好的成绩认真写了文章,却依旧没有一个好的阅读量认真完成了任务,却依旧得不到领导的赏识和表
努力做更好的自己金无足赤,人无完人。无论你是什么样的都会有人不喜欢你,既然左右都有人不喜欢你,不如潇潇晒晒的做自己。不要太在乎别人的眼光,要当自己人生的中主角,而不是跑到别人的人生中当配角。要乐观
史前掠夺者的出土巴塔哥尼亚多种恐龙中的肉食者由德克萨斯大学奥斯汀分校领导的一项研究提供了对晚白垩纪期间巴塔哥尼亚恐龙和鸟类多样性的一瞥,就在非鸟类恐龙灭绝之前。这些化石代表了来自巴塔哥尼亚智利部分的theropods一个包括