当前位置: 首页 > web >正文

Resilience4j 实战—使用方式及配置详解

在真实项目中,Resilience4j 的使用方式非常灵活,既可以用注解简化开发,也能用代码手动配置实现灵活控制,还能通过配置文件统一管理参数。关于生效范围,也并非只能对单个接口生效,下面我们逐一说明。

一、三种常用使用方式及适用场景

1. 注解形式 —— 最常用(推荐 Spring Boot 项目)

特点

通过注解直接标记需要保护的方法,底层通过 AOP 实现功能,代码侵入性低,配置简单。

使用示例

首先需要在 Spring Boot 项目中添加依赖(以 Maven 为例):

<dependency><groupId>io.github.resilience4j</groupId><artifactId>resilience4j-spring-boot2</artifactId><version>1.7.1</version>
</dependency>

然后在接口方法上添加注解:

@Service
public class OrderService {// 熔断注解:指定熔断实例名和降级方法@CircuitBreaker(name = "paymentService", fallbackMethod = "paymentFallback")// 重试注解:指定重试实例名@Retry(name = "paymentService")public String callPaymentService(String orderId) {// 调用支付服务(实际项目中是HTTP调用或RPC调用)return "支付服务处理订单:" + orderId;}// 降级方法(参数和返回值需与原方法一致)public String paymentFallback(String orderId, Exception e) {return "订单" + orderId + "暂时无法支付,请稍后重试";}
}
适用场景
  • 大多数 Spring Boot/Spring Cloud 微服务项目

  • 不需要动态修改配置逻辑的场景

  • 希望代码简洁,减少手动配置的场景

2. 代码配置形式(手动创建 Config)—— 最灵活

特点

通过CircuitBreakerConfig.custom()等代码手动创建配置,可根据业务逻辑动态调整参数(比如根据时间、用户类型修改配置)。

使用示例
@Service
public class UserService {private final CircuitBreaker userServiceCircuitBreaker;// 构造方法中初始化熔断配置public UserService() {// 动态配置:比如非高峰时段失败阈值设高一点int failureThreshold = LocalTime.now().isAfter(LocalTime.of(20, 0)) ? 70 : 50;CircuitBreakerConfig config = CircuitBreakerConfig.custom().failureRateThreshold(failureThreshold).waitDurationInOpenState(Duration.ofSeconds(10)).build();this.userServiceCircuitBreaker = CircuitBreaker.of("userService", config);}public String queryUser(String userId) {// 手动用熔断包装调用return Try.ofSupplier(CircuitBreaker.decorateSupplier(userServiceCircuitBreaker, () -> "查询用户" + userId + "成功")).recover(Exception.class, "查询用户失败").get();}
}
适用场景
  • 需要动态调整配置参数的场景(比如根据时段、用户等级修改阈值)

  • 非 Spring 环境的项目

  • 需要在代码中手动控制熔断 / 重试逻辑的场景

3. 配置文件(yaml)形式 —— 参数集中管理

特点

通过 yaml 或 properties 文件配置参数,无需修改代码即可调整阈值、超时时间等,适合环境差异化配置(开发 / 测试 / 生产用不同参数)。

使用示例

在application.yml中配置:

resilience4j:circuitbreaker:instances:# 支付服务熔断配置paymentService:failureRateThreshold: 50waitDurationInOpenState: 5000permittedNumberOfCallsInHalfOpenState: 1retry:instances:# 支付服务重试配置paymentService:maxAttempts: 3waitDuration: 1000retryExceptions:- java.io.IOException

然后在注解中直接引用实例名(和配置文件中instances下的名称对应):

@CircuitBreaker(name = "paymentService", fallbackMethod = "paymentFallback")
public String callPaymentService(String orderId) {// 业务逻辑
}
适用场景
  • 需要统一管理配置参数的项目

  • 不同环境(开发 / 生产)需要不同配置的场景

  • 希望通过配置中心(如 Nacos、Apollo)动态刷新参数的场景

二、配置文件(yaml)完整说明

yaml 配置的核心是按 “功能类型→实例名→参数” 的层级结构定义,支持所有核心功能的配置:

resilience4j:# 熔断配置circuitbreaker:instances:serviceA:  # 实例名(注解中name需对应)failureRateThreshold: 50  # 失败率阈值(百分比)waitDurationInOpenState: 5000  # 开放状态持续时间(毫秒)permittedNumberOfCallsInHalfOpenState: 2  # 半开状态允许的调用次数# 重试配置retry:instances:serviceA:maxAttempts: 3  # 最大尝试次数(含首次调用)waitDuration: 1000  # 重试间隔(毫秒)retryExceptions:  # 需要重试的异常- java.io.IOException- java.net.SocketTimeoutException# 限流配置ratelimiter:instances:serviceA:limitRefreshPeriod: 1000  # 限流刷新周期(毫秒)limitForPeriod: 10  # 周期内允许的请求数# 超时配置timeout:instances:serviceA:timeoutDuration: 2000  # 超时时间(毫秒)

这种配置方式中,instances下的每个 key(如 serviceA)就是实例名,在代码中通过@CircuitBreaker(name = “serviceA”)引用即可生效。

三、如何实现批量 / 全局生效?

Resilience4j 支持通过 “全局默认配置” 和 “批量匹配” 两种方式实现非单个接口生效。

1. 全局默认配置 —— 所有实例共用基础参数

在 yaml 中配置默认值,未单独配置的实例会继承默认参数:

resilience4j:circuitbreaker:configs:default:  # 默认配置failureRateThreshold: 50waitDurationInOpenState: 5000instances:serviceA:  # 继承默认配置,可覆盖部分参数failureRateThreshold: 60  # 覆盖默认的50serviceB:  # 完全使用默认配置

2. 批量匹配接口 —— 通过 AOP 切点实现

在 Spring 项目中,可通过自定义 AOP 切点,对某个包下的所有接口统一应用 Resilience4j 功能。

示例:对com.example.service包下所有方法添加熔断

@Configuration
@Aspect
public class ResilienceGlobalAspect {private final CircuitBreaker circuitBreaker;public ResilienceGlobalAspect() {CircuitBreakerConfig config = CircuitBreakerConfig.custom().failureRateThreshold(50).build();this.circuitBreaker = CircuitBreaker.of("globalService", config);}// 切点:匹配com.example.service包下所有公共方法@Pointcut("execution(* com.example.service..*(..)) && public")public void servicePointcut() {}// 环绕通知应用熔断@Around("servicePointcut()")public Object wrapWithCircuitBreaker(ProceedingJoinPoint joinPoint) throws Throwable {// 用熔断包装目标方法调用Supplier<Object> supplier = () -> {try {return joinPoint.proceed();} catch (Throwable e) {throw new RuntimeException(e);}};return Try.ofSupplier(CircuitBreaker.decorateSupplier(circuitBreaker, supplier)).recover(Exception.class, "服务暂时不可用").get();}
}

3. 按业务分组生效 —— 实例名对应业务分组

比如将所有支付相关接口用同一个实例名,共享一套配置:

// 支付相关接口1
@CircuitBreaker(name = "paymentGroup", fallbackMethod = "paymentFallback")
public String createPayment(String orderId) { ... }// 支付相关接口2
@CircuitBreaker(name = "paymentGroup", fallbackMethod = "paymentFallback")
public String queryPaymentStatus(String paymentId) { ... }

yaml 中只需配置paymentGroup一个实例,两个接口会共用该配置。

四、三种方式的选择建议

使用方式优点缺点推荐场景
注解 + yaml 配置简洁、易维护、支持动态配置灵活性稍弱大多数 Spring Boot 微服务项目
代码手动配置可动态调整、灵活性极高代码稍繁琐,需手动管理实例需要个性化配置逻辑的场景
全局 AOP 配置批量生效,无需逐个标记不适合精细控制单个接口通用服务层批量保护

实际项目中通常是 “注解 + yaml” 为主,个别特殊接口用代码手动配置,配合全局默认配置减少重复工作。

五、总结

Resilience4j 在真实项目中并非只能用某一种方式,而是可以根据需求灵活选择:

  • 简单场景用 “注解 + yaml”,高效又省心;

  • 复杂场景用代码配置,实现动态参数调整;

  • 批量生效可通过全局配置、AOP 切点或业务分组实现,无需逐个接口配置。

记住一个原则:能通过配置解决的就不要写代码,需要个性化逻辑的再手动编码,这样既能保证开发效率,又能满足灵活需求。

http://www.xdnf.cn/news/16615.html

相关文章:

  • Centos 7 命令:ip addr
  • MySQL复习
  • YOLOv8 基于RTSP流目标检测
  • OSPF路由协议
  • SpringCloud01——项目演变、微服务远程调用三种方式、springcloud介绍、nacos注册中心
  • 从“人工核验”到“智能鉴防”:护照鉴伪设备的科技革命
  • AR远程协作系统设计:虚实融合场景下的设备维护操作指引界面
  • Linux学习--C语言(指针3)
  • tsc命令深入全面讲解
  • 【Linux】编辑器vim和编译器gcc/g++
  • 【计算机网络】计算机网络中光猫、交换机、路由器、网关、MAC地址是什么?两台电脑是如何联通的?
  • leetcode 2044. 统计按位或能得到最大值的子集数目 中等
  • 自定义View学习记录 plinko游戏View
  • 【OS】真题 2015
  • 架构实战——互联网架构模板(“开发层”和“服务层”技术)
  • JavaWeb 入门:HTML 基础与实战详解(Java 开发者视角)
  • python对象的__dict__属性详解
  • 5G MBS(组播广播服务)深度解析:从标准架构到商用实践
  • Linux 题目总结参考
  • 低速信号设计之 SMBUS 篇
  • 零基础学习性能测试第六章:性能难点-Jmeter文件上传场景压测
  • 网络虚拟化:veth,bridge,network namespace与docker网络
  • Word和WPS文字如何制作分栏试卷?想分几栏分几栏
  • Java面试实战:安全框架与大数据技术深度解析
  • 【模电笔记】—— 波形发生电路(波形振荡器)
  • ArKTS:List 数组
  • 每日算法刷题Day55:7.27:leetcode 复习完第K小/大+栈4道题,用时1h50min
  • Python初学OpenCV:图像预处理进阶指南(二)
  • 数据结构 堆(4)---TOP-K问题
  • Android Framework知识点