1 新建一个微服务模块
我们在cloud-payment-service
模块中新增一个controller
以提供给其它微服务模块调用。
@RestController
public class PayCircuitController {
@GetMapping("/pay/circuit/{id}")
public String myCircuit(@PathVariable("id") Integer id){
if(id == -4) {
throw new RuntimeException("ID不能为负数");
}
if(id == 999) {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "Hello Circuit! InputId: " + id + " \t" + IdUtil.simpleUUID();
}
}
根据ID返回一段字符串,当ID为负数或者999使用特殊处理,其它情况直接返回字符串。
2 编写OpenFeign访问接口
@FeignClient(value = "cloud-payment-service", path = "/pay")
@RestController
public interface PayFeignApi {
@GetMapping("/circuit/{id}")
public String myCircuit(@PathVariable("id") Integer id);
}
3 引入依赖
<!-- Circuit断路器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
<!-- 断路器保护需要AOP实现 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
4 配置文件
resilience4j:
timelimiter:
configs:
default:
timeout-duration: 10s #
circuitbreaker:
configs:
default:
failure-rate-threshold: 50 # 设置50%失败打开断路器,超过失败百分比的circuitBreaker变为OPEN状态
slow-call-duration-threshold: 2s # 慢调用时间阀值
slow-call-rate-threshold: 30 # 慢调用百分比峰值,断路器时间大于slow-call-duration-threshold就是慢调用,当达到峰值就打开断路器
sliding-window-type: TIME_BASED # 滑动窗口类型
sliding-window-size: 2 # 滑动窗口大小配置COUNT_BASED表示6个请求 配置为TIME_BASED表示6s
minimum-number-of-calls: 2 # 断路器计算失败率或者慢调用率之前所需要的最小样本
automatic-transition-from-open-to-half-open-enabled: true # 是否开启自动从开启状态过渡到半开状态。默认为true
wait-duration-in-open-state: 5s # 从OPEN到HALF_OPEN需要等待时间
permitted-number-of-calls-in-half-open-state: 2 # 半开状态最大请求数
record-exceptions:
- java.lang.Exception
instances:
cloud-payment-service:
base-config: default
5 编写业务
@RestController
public class OrderCircuitController {
@Resource
private PayFeignApi payFeignApi;
@GetMapping("/feign/pay/circuit/{id}")
@CircuitBreaker(name = "cloud-payment-service" , fallbackMethod = "myCircuitFullBack")
public String myCircuitBreaker(@PathVariable("id") Integer id){
return payFeignApi.myCircuit(id);
}
@Operation(summary = "服务降级后的处理方法")
public String myCircuitFullBack(Integer id,Throwable e){
return "系统繁忙,请稍后再试!!";
}
}
6 测试