沉梦听雨的编程指南 沉梦听雨的编程指南
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM
  • 新特性
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 基础篇
  • MySql
  • Redis
  • 达梦数据库
  • Spring
  • SpringBoot
  • Mybatis
  • Shiro
  • 设计须知
  • UML画图
  • 权限校验
  • 设计模式
  • API网关
  • 网络通信
  • 消息队列
  • SpringCloud
  • 分布式事务
  • 云存储
  • 搜索引擎
  • 多媒体框架
  • 虚拟机
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • 随笔
  • 前端环境搭建
  • HTML与CSS
  • JS学习
  • Axios入门
  • Vue Router入门
  • Pinia入门
  • Vue3入门
  • Vue3进阶
  • 黑马Vue3
  • 脚手架搭建
  • 瑞吉外卖
  • 黑马点评
  • vue-blog
  • 沉梦接口开放平台
  • 用户中心
  • 聚合搜索平台
  • 仿12306项目
  • 壁纸小程序项目
  • RuoYi-Vue
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
Github (opens new window)

沉梦听雨

时间是最好的浸渍剂,而沉淀是最好的提纯器🚀
首页
  • 基础篇
  • 集合篇
  • 并发篇
  • JVM
  • 新特性
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 基础篇
  • MySql
  • Redis
  • 达梦数据库
  • Spring
  • SpringBoot
  • Mybatis
  • Shiro
  • 设计须知
  • UML画图
  • 权限校验
  • 设计模式
  • API网关
  • 网络通信
  • 消息队列
  • SpringCloud
  • 分布式事务
  • 云存储
  • 搜索引擎
  • 多媒体框架
  • 虚拟机
  • 开发工具篇
  • 工具库篇
  • 开发技巧篇
  • 工具类系列
  • 随笔
  • 前端环境搭建
  • HTML与CSS
  • JS学习
  • Axios入门
  • Vue Router入门
  • Pinia入门
  • Vue3入门
  • Vue3进阶
  • 黑马Vue3
  • 脚手架搭建
  • 瑞吉外卖
  • 黑马点评
  • vue-blog
  • 沉梦接口开放平台
  • 用户中心
  • 聚合搜索平台
  • 仿12306项目
  • 壁纸小程序项目
  • RuoYi-Vue
  • 博客搭建
  • 网站收藏箱
  • 断墨寻径摘录
  • 费曼学习法
Github (opens new window)
  • API网关

  • 网络通信

  • 消息队列

  • Spring Cloud

    • Spring Cloud Alibaba 从入门到实战

      • 基础知识篇
      • 分布式配置
      • 服务注册与发现
      • 分布式服务调用
      • 服务熔断和限流
      • 分布式消息(事件)驱动
      • 分布式事务
    • SpringCloud Stream学习
    • Nacos入门
    • Apollo入门
    • Resilience4j入门
      • 引言
      • 为什么选择 Resilience4j?
      • Resilience4j 核心模块概览
      • 熔断器状态
        • 1. 关闭状态(Closed / 状态值通常为 0)
        • 2. 打开状态(Open / 状态值通常为 1)
        • 3. 半开状态(Half-Open / 状态值通常为 2)
        • 状态转换图
        • 在 Resilience4j 中的状态值(用于监控)
        • 小结
      • 快速上手:Spring Boot 集成 Resilience4j
        • 1. 添加依赖(Maven)
        • 2. 配置文件(application.yml)
      • 实战:四种核心模式代码示例
        • 场景假设
        • 1. 熔断器(CircuitBreaker)
        • 2. 限流器(RateLimiter)
        • 3. 重试(Retry)
        • 4. 组合使用:熔断 + 重试 + 限流
      • 注解驱动开发(推荐)
      • 监控与指标
      • 最佳实践建议
  • 分布式事务

  • 云存储

  • 搜索引擎

  • 多媒体框架

  • 虚拟机

  • 微服务
  • Spring Cloud
沉梦听雨
2025-12-19
目录

Resilience4j入门

# Resilience4j 入门与实战

# 引言

构建高可用微服务的容错利器

在分布式系统中,故障是常态而非例外。如何优雅地处理服务调用失败、避免雪崩效应,是每个 Java 微服务开发者必须面对的问题。Resilience4j 作为轻量级、函数式、面向 Java 8+ 的容错库,正逐渐成为 Spring Cloud 生态中 Hystrix 的主流替代方案。本文将带你全面掌握 Resilience4j 的核心模块、使用方式及最佳实践。

📚 官方文档:https://resilience4j.readme.io/ 🧪 示例代码:https://github.com/resilience4j/resilience4j-spring-boot2-demo

# 为什么选择 Resilience4j?

在 Hystrix 宣布停止维护后,社区急需一个现代化的容错解决方案。Resilience4j 应运而生,其优势包括:

  • 轻量无依赖:不强制依赖任何框架(如 Spring),可独立使用。
  • 函数式编程风格:基于 Vavr(原 Javaslang)函数式库,支持 Lambda 表达式。
  • 模块化设计:按需引入所需功能(熔断、限流、重试等),避免“大而全”。
  • 与 Spring Boot 深度集成:通过 spring-boot-starter 快速配置。
  • 丰富的监控指标:天然支持 Micrometer,无缝对接 Prometheus + Grafana。

# Resilience4j 核心模块概览

Resilience4j 提供六大核心组件,可单独或组合使用:

模块 功能
CircuitBreaker 熔断器:快速失败,防止级联故障
RateLimiter 限流器:控制单位时间内的请求数
Retry 重试机制:对失败操作自动重试
Bulkhead 隔离舱:限制并发数,防止单个服务耗尽资源
TimeLimiter 超时控制:限制异步操作的最大等待时间
Cache 缓存:对结果进行缓存(较少使用)

💡 实际项目中最常用的是前四项。

# 熔断器状态

在 Resilience4j 中,**熔断器(Circuit Breaker)**有三种核心状态,用于控制对外部服务的调用行为,防止故障蔓延。

这三种状态分别是:


# 1. 关闭状态(Closed / 状态值通常为 0)

  • ✅ 正常工作状态。
  • 所有请求都正常发送到下游服务。
  • 熔断器会监控调用的成功与失败情况(例如:记录最近 N 次调用的失败率)。
  • 触发条件:当失败率超过设定阈值(如 failure-rate-threshold: 50%)且满足最小请求数(minimum-number-of-calls),熔断器会跳转到“打开”状态。

📌 类比:电路正常通电,灯亮着。


# 2. 打开状态(Open / 状态值通常为 1)

  • ❌ 熔断已触发,拒绝所有请求。
  • 所有对该服务的调用立即失败,不会真正发出请求(避免加重下游负担)。
  • 直接抛出 CallNotPermittedException(或执行 fallback 逻辑)。
  • 目的:给下游服务“喘息时间”,防止雪崩。
  • 自动恢复机制:经过一段预设时间(wait-duration-in-open-state,如 10 秒)后,熔断器会自动进入“半开”状态,尝试恢复。

📌 类比:保险丝熔断,电路断开,灯灭了。


# 3. 半开状态(Half-Open / 状态值通常为 2)

  • 🔍 试探性恢复状态。
  • 允许有限数量的请求通过(由 permitted-number-of-calls-in-half-open-state 控制,如 3 个)。
  • 如果这些试探请求全部成功 → 熔断器回到“关闭”状态,恢复正常调用。
  • 如果任一请求失败 → 熔断器重新回到“打开”状态,继续熔断。

📌 类比:轻轻合上电闸,看灯是否还烧保险丝——如果正常就彻底恢复供电,否则再次断开。


# 状态转换图

         [失败率过高]
   Closed ——————————→ Open
     ↑                  |
     |                  | [等待超时]
     |                  ↓
     └—————— Half-Open ←——————┘
            ↑      |
            |成功  |失败
            └──────┘
1
2
3
4
5
6
7
8
9

# 在 Resilience4j 中的状态值(用于监控)

当你集成 Micrometer + Prometheus 时,指标 resilience4j_circuitbreaker_state 会暴露以下数值:

状态 数值
CLOSED 0
OPEN 1
HALF_OPEN 2

例如:

resilience4j_circuitbreaker_state{name="userServiceCB"} == 1
1

表示 userServiceCB 熔断器当前处于打开状态,所有调用被拒绝。


# 小结

状态 是否放行请求 作用
关闭 ✅ 是 正常调用,监控失败率
打开 ❌ 否 快速失败,保护下游
半开 ⚠️ 有限放行 试探服务是否恢复,决定是否闭合

# 快速上手:Spring Boot 集成 Resilience4j

# 1. 添加依赖(Maven)

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

<!-- 可选:集成 Micrometer 监控 -->
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-core</artifactId>
</dependency>
1
2
3
4
5
6
7
8
9
10
11

注意:Spring Boot 3 用户应使用 resilience4j-spring-boot3。

# 2. 配置文件(application.yml)

resilience4j:
  circuitbreaker:
    instances:
      userServiceCB:
        failure-rate-threshold: 50          # 失败率阈值(%)
        minimum-number-of-calls: 5          # 最小请求次数(才触发熔断判断)
        wait-duration-in-open-state: 10s    # 熔断开启后,等待多久进入半开状态
        permitted-number-of-calls-in-half-open-state: 3 # 半开状态下,试探请求次数
        sliding-window-size: 10             # 滑动窗口大小
        sliding-window-type: COUNT_BASED    # 基于计数(也可选 TIME_BASED)

  ratelimiter:
    instances:
      userServiceRL:
        limit-for-period: 10                # 每周期允许10次请求
        limit-refresh-period: 1s            # 周期为1秒
        timeout-duration: 0                 # 获取许可的等待超时(0表示立即失败)

  retry:
    instances:
      userServiceRetry:
        max-attempts: 3                     # 最多重试3次
        wait-duration: 100ms                # 重试间隔
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 实战:四种核心模式代码示例

# 场景假设

调用用户服务 getUserById(id),需添加容错能力。

# 1. 熔断器(CircuitBreaker)

@Service
public class UserService {

    @Autowired
    private CircuitBreakerRegistry circuitBreakerRegistry;

    public String getUserById(String id) {
        CircuitBreaker cb = circuitBreakerRegistry.circuitBreaker("userServiceCB");
        
        Supplier<String> decorated = CircuitBreaker
            .decorateSupplier(cb, () -> externalCallToUserApi(id));
        
        // 提供 fallback
        return Try.ofSupplier(decorated)
                  .recover(throwable -> "Default User")
                  .get();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

使用 @CircuitBreaker(name = "userServiceCB", fallbackMethod = "fallback") 注解更简洁(需启用 AOP)。

# 2. 限流器(RateLimiter)

public String getUserWithRateLimit(String id) {
    RateLimiter rl = rateLimiterRegistry.rateLimiter("userServiceRL");
    
    Supplier<String> decorated = RateLimiter
        .decorateSupplier(rl, () -> externalCallToUserApi(id));
    
    return Try.ofSupplier(decorated)
              .recover(RequestNotPermitted.class, e -> "Too Many Requests!")
              .get();
}
1
2
3
4
5
6
7
8
9
10

# 3. 重试(Retry)

public String getUserWithRetry(String id) {
    Retry retry = retryRegistry.retry("userServiceRetry");
    
    Supplier<String> decorated = Retry
        .decorateSupplier(retry, () -> externalCallToUserApi(id));
    
    return Try.ofSupplier(decorated)
              .get(); // 自动重试,最终抛出异常或成功
}
1
2
3
4
5
6
7
8
9

# 4. 组合使用:熔断 + 重试 + 限流

public String getUserRobust(String id) {
    CircuitBreaker cb = circuitBreakerRegistry.circuitBreaker("userServiceCB");
    RateLimiter rl = rateLimiterRegistry.rateLimiter("userServiceRL");
    Retry retry = retryRegistry.retry("userServiceRetry");

    Supplier<String> supplier = () -> externalCallToUserApi(id);
    Supplier<String> decorated = decorateSupplier(supplier, cb, rl, retry);

    return Try.ofSupplier(decorated)
              .recover(this::fallback)
              .get();
}

private Supplier<String> decorateSupplier(Supplier<String> supplier,
                                         CircuitBreaker cb,
                                         RateLimiter rl,
                                         Retry retry) {
    return CircuitBreaker.decorateSupplier(cb,
           RateLimiter.decorateSupplier(rl,
           Retry.decorateSupplier(retry, supplier)));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

⚠️ 注意装饰顺序:通常 限流 → 熔断 → 重试,但需根据业务调整。

# 注解驱动开发(推荐)

Resilience4j 支持通过注解简化代码:

@Service
public class UserService {

    @Retry(name = "userServiceRetry", fallbackMethod = "fallback")
    @RateLimiter(name = "userServiceRL")
    @CircuitBreaker(name = "userServiceCB", fallbackMethod = "fallback")
    public String getUserById(String id) {
        return externalCallToUserApi(id);
    }

    private String fallback(String id, Exception ex) {
        log.warn("Fallback for user: {}, error: {}", id, ex.getMessage());
        return "Default User";
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

需在启动类添加 @EnableAspectJAutoProxy 并确保 AOP 生效。

# 监控与指标

Resilience4j 自动暴露 Micrometer 指标,例如:

  • resilience4j_circuitbreaker_state:熔断器状态(0=关闭,1=打开,2=半开)
  • resilience4j_ratelimiter_available_permissions:剩余许可数
  • resilience4j_retry_calls:重试次数统计

配合 Prometheus + Grafana,可构建实时容错看板。

# 最佳实践建议

  1. 合理设置熔断参数:避免过于敏感(频繁熔断)或迟钝(无法保护系统)。
  2. 重试需幂等:确保被调用接口支持重复请求。
  3. 限流与业务匹配:突发流量 vs 平稳流量,选择 TIME_BASED 或 COUNT_BASED。
  4. fallback 逻辑轻量:避免 fallback 本身成为瓶颈。
  5. 组合策略有顺序:通常先限流(入口控制),再熔断(故障隔离),最后重试(恢复尝试)。
上次更新: 2025/12/19 17:41:05
Apollo入门
认识Seata

← Apollo入门 认识Seata→

Theme by Vdoing | Copyright © 2023-2025 沉梦听雨 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式