Spring Cloud Circuit Breaker快速入门Demo

1.什么是Spring Cloud Circuit Breaker?

Spring Cloud Circuit breaker提供了一个跨越不同断路器实现的抽象。它提供了一个一致的API,可以在你的应用程序中使用,允许你的开发者选择最适合你的应用程序需求的断路器实现。

它还支持的实现有如下几种

  • Resilience4j
  • Hystrix
  • Sentinel
  • Spring Retry

Resilience4j概述

Resilience4J 是一个针对 Java 8 应用程序的轻量级容错和弹性库。它设计用于在分布式系统中的服务之间提供弹性和容错性。Resilience4J 的名字来源于它提供的核心功能,即让系统(服务)能够“弹性”(resilient)地应对各种失败情况,包括网络问题、第三方服务故障等。 Resilience4J 提供了以下功能:

  1. 断路器(Circuit Breaker):当检测到服务异常或超时,断路器会打开,阻止进一步的请求发送到该服务。一段时间后(通常是秒级),断路器会进入半开状态,允许一个测试请求通过以检查服务是否恢复。如果请求成功,断路器关闭;如果失败,断路器会再次打开。
  2. 限流(Rate Limiter):限制进入系统的请求速率,防止系统过载。这可以通过令牌桶算法或滑动窗口算法实现。
  3. 隔离(Isolation):通过信号量或线程池隔离不同的服务调用,防止一个服务的失败影响到其他服务。
  4. 超时(Timeouts):为服务调用设置超时时间,超过时间后会触发超时异常。
  5. 重试(Retry):在遇到特定异常时自动重试服务调用,可以配置重试次数和间隔。
  6. 缓存(Caching):提供缓存机制,以避免重复执行计算密集型或远程调用。

Resilience4j 的 CircuitBreaker 实现原理如下

  1. 断路器的状态:CircuitBreaker 具有三种正常状态:CLOSED(关闭)、OPEN(打开)和 HALFOPEN(半开),以及两个特殊状态:DISABLED(禁用)和 FORCEDOPEN(强制打开)。这些状态通过有限状态机进行管理。
  2. 打开和关闭逻辑:当被保护的服务或资源发生故障或长时间不可用时,断路器会迅速切换到 OPEN 状态,阻止更多的请求发送到该服务或资源。在 OPEN 状态下,系统会定期发送测试请求,以检查故障是否已经解决。如果测试请求成功,断路器会切换到 HALFOPEN 状态,允许一个请求发送到该服务或资源。如果这个请求成功,断路器会切换到 CLOSED 状态,否则会重新切换到 OPEN 状态。
  3. 故障率计算:为了判断是否打开断路器,需要收集一定数量的请求数据。在 Resilience4j 中,需要至少填充一个环形缓冲区(Ring Bit Buffer),才能开始计算故障率。环形缓冲区的大小决定了需要多少次请求才能进行故障率的计算。
  4. 环形缓冲区:Resilience4j 使用环形缓冲区来存储请求状态的数据结构,这与 Hystrix 使用的滑动窗口不同。环形缓冲区使用位集合(BitSet)实现,每个位代表一个请求的状态(成功或失败)。环形缓冲区的大小决定了能够存储的请求数量。例如,一个大小为 10 的缓冲区可以存储 1024 个请求状态。
  5. 配置选项:Resilience4j 提供了丰富的配置选项,如故障率阈值、打开状态下的等待时间、半开状态下允许的最大请求数等,开发者可以根据需求进行灵活配置。

通过上述原理,Resilience4j 的 CircuitBreaker 能够有效地保护分布式系统免受故障的影响,提高系统的可用性和健壮性。

2.代码工程

实验目的

利用Circuit Breaker实现接口熔断和自动恢复

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>springcloud-demo</artifactId><groupId>com.et</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>spring-cloud-circuit-breaker</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency></dependencies>
</project>

controller

注解实现
关键组件
  1. name

    • 指定断路器实例的名称。这个名称应该与配置文件中定义的实例名称匹配。系统会根据这个名称查找断路器的配置设置。
  2. fallbackMethod

    • 指定当断路器打开或注解的方法抛出异常时调用的备用方法。备用方法应具有与原始方法相同的返回类型,并且可以选择接受相同的参数,最后还可以接受一个 Throwable 参数以捕获异常。
断路器状态
  • 关闭(Closed):断路器允许调用服务并监控结果。如果失败率超过配置的阈值,断路器将转为打开状态。

  • 打开(Open):断路器会短路对服务的调用,立即返回失败或调用备用方法。经过配置的等待时间后,断路器将转为半开状态。

  • 半开(Half-Open):断路器允许有限数量的测试调用。如果这些调用成功,断路器将转回关闭状态;如果失败,则返回到打开状态。

package com.et.controller;import io.github.resilience4j.circuitbreaker.CallNotPermittedException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;@RestController
@RequestMapping("/annotation")
public class MyController {private final io.github.resilience4j.circuitbreaker.CircuitBreaker circuitBreaker;private boolean simulateFailure = true;public MyController(CircuitBreakerRegistry circuitBreakerRegistry) {this.circuitBreaker = circuitBreakerRegistry.circuitBreaker("order-service");}@GetMapping("/my-service")@CircuitBreaker(name = "order-service", fallbackMethod = "fallbackMethod")public String myService() {System.out.println("Circuit Breaker State: " + circuitBreaker.getState());System.out.println("Circuit Breaker name: " + circuitBreaker.getName());System.out.println("Circuit Breaker config: " + circuitBreaker.getCircuitBreakerConfig().toString());if (simulateFailure) {throw new RuntimeException("Simulated failure");}return "Service is up";}public String fallbackMethod(Throwable throwable) {if (throwable instanceof CallNotPermittedException) {return "Circuit Breaker is OPEN, request not permitted";}return "Fallback response";}@GetMapping("/toggle-failure")public String toggleFailure() {simulateFailure = !simulateFailure;return "Failure simulation is now " + (simulateFailure ? "ON" : "OFF");}
}

自定义实现

package com.et.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import io.github.resilience4j.circuitbreaker.CallNotPermittedException;import java.util.function.Supplier;@RestController
public class DemoController {private final CircuitBreaker circuitBreaker;private boolean simulateFailure = true;public DemoController(CircuitBreakerRegistry circuitBreakerRegistry) {this.circuitBreaker = circuitBreakerRegistry.circuitBreaker("myCircuitBreaker");}@GetMapping("/my-service")public String myService() {System.out.println("Circuit Breaker State: " + circuitBreaker.getState());Supplier<String> decoratedSupplier = CircuitBreaker.decorateSupplier(circuitBreaker, () -> {if (simulateFailure) {throw new RuntimeException("Simulated failure");}return "Service is up";});try {return decoratedSupplier.get();} catch (CallNotPermittedException e) {return "Circuit Breaker is OPEN, request not permitted";} catch (Exception e) {return "Fallback response";}}@GetMapping("/toggle-failure")public String toggleFailure() {simulateFailure = !simulateFailure;return "Failure simulation is now " + (simulateFailure ? "ON" : "OFF");}
}

配置文件

resilience4j.circuitbreaker:instances:myCircuitBreaker:slidingWindowSize: 10failureRateThreshold: 50waitDurationInOpenState: 30spermittedNumberOfCallsInHalfOpenState: 3order-service:sliding-window-type: COUNT_BASEDfailure-rate-threshold: 10minimum-number-of-calls: 5automatic-transition-from-open-to-half-open-enabled: truewait-duration-in-open-state: 5spermitted-number-of-calls-in-half-open-state: 3sliding-window-size: 10register-health-indicator: true
myCircuitBreaker
  • slidingWindowSize: 10: This sets the size of the sliding window, which is used to record the outcome of calls. In this case, it records the last 10 calls.

  • failureRateThreshold: 50: This sets the failure rate threshold as a percentage. If the failure rate is equal to or greater than 50%, the circuit breaker transitions to the open state.

  • waitDurationInOpenState: 30s: This specifies the time that the circuit breaker should stay open before transitioning to half-open. Here, it is set to 30 seconds.

  • permittedNumberOfCallsInHalfOpenState: 3: This sets the number of calls that are allowed to pass through when the circuit breaker is in the half-open state. If these calls are successful, the circuit breaker transitions back to closed.

order-service
  • sliding-window-type: COUNT_BASED: This specifies the type of sliding window. COUNT_BASED means the window is based on a fixed number of calls.

  • failure-rate-threshold: 10: This sets a lower failure rate threshold of 10%. If the failure rate reaches this level, the circuit breaker will open.

  • minimum-number-of-calls: 5: This sets the minimum number of calls that must be recorded before the failure rate can be calculated. This prevents the circuit breaker from opening prematurely.

  • automatic-transition-from-open-to-half-open-enabled: true: This enables automatic transition from open to half-open state after the wait duration has elapsed.

  • wait-duration-in-open-state: 5s: This specifies a shorter wait duration of 5 seconds for the circuit breaker to stay open before transitioning to half-open.

  • permitted-number-of-calls-in-half-open-state: 3: Similar to myCircuitBreaker, this sets the number of test calls allowed in the half-open state.

  • sliding-window-size: 10: This sets the sliding window size to 10 calls, similar to myCircuitBreaker.

  • register-health-indicator: true: This enables the registration of a health indicator for the circuit breaker, which can be used for monitoring purposes.

启动类

Spring AOP在使用注解风格的切面时,需要AspectJ的支持,确保在Spring Boot应用中启用了AOP支持,并启用@EnableAspectJAutoProxy注解

package com.et;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@SpringBootApplication
@EnableAspectJAutoProxy
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}}

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

  • https://github.com/Harries/springcloud-demo(spring cloud Circuit Breaker )

3.测试

启动应用程序

非注解方式

  1. 初始请求:访问 /my-service,确保在 simulateFailure 为 true 时抛出异常。
  2. 多次失败请求:连续多次访问 /my-service,以达到失败率阈值,触发断路器进入 OPEN 状态。
  3. 检查状态:在控制台中观察断路器状态输出,确保状态变为 OPEN
  4. 访问 /toggle-failure:切换 simulateFailure 为 false
  5. 等待并测试:等待 waitDurationInOpenState 时间后,再次访问 /my-service,观察断路器状态变化和请求结果。

注解方式

  1. 初始请求:访问 /annotation/my-service,确保在 simulateFailure 为 true 时抛出异常。
  2. 多次失败请求:连续多次访问 /annotation/my-service,以达到失败率阈值,触发断路器进入 OPEN 状态。
  3. 检查状态:在控制台中观察断路器状态输出,确保状态变为 OPEN
  4. 访问 /annotation/toggle-failure:切换 simulateFailure 为 false
  5. 等待并测试:等待 waitDurationInOpenState 时间后,再次访问 /annotation/my-service,观察断路器状态变化和请求结果。

4.引用

  • Spring Cloud Circuit Breaker
  • Spring Cloud Circuit Breaker快速入门Demo | Harries Blog™

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/3510.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

生物医药产业前景如何?怎样开展生物医药产业分析?

▶生物医药产业前景 生物医药产业的前景是非常广阔的&#xff0c;主要呈现以下几大特点&#xff1a; 1.市场规模增长&#xff1a;预计到2029年&#xff0c;中国医药制造规上企业营业收入将达到5.4万亿元&#xff0c;2024-2029年年均增长率达到14.04%。这表明生物医药产业将继…

Ubuntu用docker安装AWVS和Nessus(含破解)

Ubuntu安装AWVS(更多搜索&#xff1a;超详细Ubuntu用docker安装AWVS和Nessus) 首先安装docker&#xff0c;通过dockers镜像安装很方便&#xff0c;且很快&#xff1b;Docker及Docker-Compose-安装教程。 1.通过docker search awvs命令查看镜像&#xff1b; docker search awvs…

大模型微调技术 --> P-Tuning v1和 P-Tuning v2

P-Tuning 是一种通过引入可学习的 提示 向量来增强预训练语言模型能力的技术&#xff0c;属于提示学习的一种。 1.背景 GPT 在 NLP 领域经过 finetuning 之后很难击败 BERT&#xff0c;主要是因为现在预训练模型的方法有很多种(主要是 MLM)&#xff0c;但在 finetune 的时候&…

Angular引用控件类

说明&#xff1a; angular 在一个控件类里面&#xff0c;引入另外一个控件类&#xff0c;这样做的好处&#xff0c;就是代码分离&#xff0c;当你一个页面存在多少类似于独立的界面时&#xff0c;可以使用这种方式&#xff0c;分离代码 更好维护程序 效果图&#xff1a; step…

124.WEB渗透测试-信息收集-ARL(15)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;123.WEB渗透测试-信息收集-ARL&#xff08;14&#xff09; 点击fofa任务下发&#xff08…

Linux命令 - 关于命令及其使用

文章目录 1 什么是命令&#xff1f;2 识别命令3 命令帮助文档4 命令别名 1 什么是命令&#xff1f; 命令可以是以下四种形式之一&#xff1a; 可执行程序&#xff1a;就像我们所看到的位于/usr/bin目录中的文件一样&#xff0c;这一类程序可以是用诸如C和C语言编写的程序编译…

【万字详文介绍】:迭代扩张卷积神经网络(IDCNN)

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

220V变5V300mA非隔离芯片WT5104

220V变5V300mA非隔离芯片WT5104 WT5104特点包括&#xff1a; - 宽输入电压&#xff1a;85VAC~265VAC&#xff0c;适应全球电网电压波动。 - 输出规格&#xff1a;稳定5V直流电&#xff0c;最大电流500mA&#xff0c;适用于轻功率电子设备。 - 工作模式灵活&#xff1a;支持CCM…

WonderWorld: Interactive 3D Scene Generation from a Single Image 论文解读

目录 一、概述 二、相关工作 1、新视图生成 2、单视图3D场景生成 3、视频生成 4、快速的3D场景表示 三、WonderWorld 1、FLAGS表示 2、引导深度扩散模块 3、单视角层次生成 4、基于几何的初始化 surfel表示 5、阶段一——生成3D场景部分 6、阶段二——用户交互控…

kkfileview4.2.1 LibreOffice_7.1.4_Linux_x86-64_rpm.tar.gz

问题 java.lang.IllegalStateException: officeHome doesnt exist or is not a directory: optlibreoffice7.1 安装 kkfileview4.2.1 LibreOffice_7.1.4_Linux_x86-64_rpm.tar.gz 测试 全过程脚本 [zengwenfenglocalhost Desktop]$ pwd /home/zengwenfeng/Desktop [zengwe…

可编辑71页PPT | 企业架构及典型设计方案

荐言分享&#xff1a;企业架构&#xff08;Enterprise Architecture, EA&#xff09;是战略与技术之间的桥梁&#xff0c;旨在确保企业的信息系统、业务流程、组织结构和技术基础设施能够协同工作&#xff0c;以支持企业的整体战略目标。它通过定义一套标准化的框架、原则、模型…

python代码获取zabbix上机器磁盘使用率

1.需要先给机器打上标记os_type: Linux或者os_type: Windows 2.代码请求获取数据&#xff1a; 先装一下相关的数据包 pip install pyzabbix from pyzabbix import ZabbixAPI import requests import urllib3 import concurrent.futuresclass ZabbixInfo():def __init__(self…

一个完整的crm系统都应该具备哪些功能?CRM系统功能盘点

前段时间我们去拜访一位企业老板&#xff0c;正好他们在开会&#xff0c;团队正在讨论如何与一位潜在的大客户达成交易。 客户对产品表现出浓厚的兴趣&#xff0c;也提出了一些具体的问题&#xff0c;例如上一次交易的详细信息、服务响应时间以及可能的折扣方案&#xff0c;但…

导师双选系统开发:Spring Boot技术详解

第一章 绪论 1.1 选题背景 如今的信息时代&#xff0c;对信息的共享性&#xff0c;信息的流通性有着较高要求&#xff0c;尽管身边每时每刻都在产生大量信息&#xff0c;这些信息也都会在短时间内得到处理&#xff0c;并迅速传播。因为很多时候&#xff0c;管理层决策需要大量信…

CTF顶级工具与资源

《Web安全》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484238&idx1&snca66551c31e37b8d726f151265fc9211&chksmc0e47a12f793f3049fefde6e9ebe9ec4e2c7626b8594511bd314783719c216bd9929962a71e6&scene21#wechat_redirect 《网安面试指南》h…

数列分块入门

本期是数列分块入门。其中的大部分题目来自hzwer在LOJ上提供的数列分块入门系列。 Blog:here (其实是对之前分块的 blog 的整理补充) sto hzwer orz %%% [转载] ---------------------------------------------------------------------------------…

模型自动绑骨,在线生成动画,神奇的网站《Mixamo》

英文名mixamo 网站地址&#xff1a;Mixamohttps://www.mixamo.com/#/首先进入需要注册&#xff0c;国内的手机号就可以&#xff0c;但是会有一些慢&#xff0c;多试几次 1、进入界面如下 2、载入自己的模型 2、绑定骨骼 拖动这几个有颜色的圈圈分别对应右图位置&#xff0c;点…

2024 CSS保姆级教程四

CSS中的动画 CSS动画&#xff08;CSS Animations&#xff09;是为层叠样式表建议的允许可扩展标记语言&#xff08;XML&#xff09;元素使用CSS的动画的模块​ 即指元素从一种样式逐渐过渡为另一种样式的过程​ 常见的动画效果有很多&#xff0c;如平移、旋转、缩放等等&#…

Docker安装anythingllm

拉镜像 docker pull mintplexlabs/anythingllm 启动 anythingllm docker run -d --name anythingllm --add-hosthost.docker.internal:host-gateway --env STORAGE_DIR/app/server/storage --health-cmd "/bin/bash/usr/local/bin/docker-healthcheck.sh || exit 1"…

格行:从新晋网红到国货之光,它究竟做对了什么?

作为一家迅速崛起的新消费品牌&#xff0c;近两年来&#xff0c;格行饱受质疑。 无论是商家还是消费者&#xff0c;都有人对其爱之恨之&#xff0c;喜欢它的人&#xff0c;认为它是正义的化身&#xff0c;价格的屠夫&#xff0c;国货的骄傲&#xff0c;原本需要花几百才能买到…