重试机制 #

一、重试概述 #

1.1 为什么需要重试 #

text
                    无重试:
                    
客户端 ──► 服务 (临时故障)
  │
  └── 请求失败 ──► 用户看到错误

                    有重试:
                    
客户端 ──► 服务 (临时故障)
  │
  ├── 第1次失败
  ├── 第2次失败
  └── 第3次成功 ──► 用户正常使用

1.2 重试场景 #

场景 是否适合重试
网络超时 ✅ 适合
服务临时不可用 ✅ 适合
业务异常 ❌ 不适合
参数校验失败 ❌ 不适合

二、基本使用 #

2.1 添加依赖 #

xml
<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-retry</artifactId>
</dependency>

2.2 配置重试 #

yaml
resilience4j:
  retry:
    configs:
      default:
        maxAttempts: 3
        waitDuration: 500ms
        enableExponentialBackoff: true
        exponentialBackoffMultiplier: 2
    instances:
      userService:
        baseConfig: default
      orderService:
        baseConfig: default
        maxAttempts: 5

2.3 使用注解 #

java
@Service
public class UserService {

    @Retry(name = "userService", fallbackMethod = "getUserFallback")
    public User getUser(Long id) {
        return userClient.getUserById(id);
    }

    private User getUserFallback(Long id, Throwable t) {
        log.error("Retry failed for getUser, id: {}", id, t);
        return createDefaultUser(id);
    }
}

三、配置详解 #

3.1 完整配置 #

yaml
resilience4j:
  retry:
    configs:
      default:
        maxAttempts: 3
        waitDuration: 500ms
        enableExponentialBackoff: true
        exponentialBackoffMultiplier: 2
        enableRandomizedWait: false
        randomizedWaitFactor: 0.5
        retryExceptions:
          - java.io.IOException
          - java.net.SocketTimeoutException
        ignoreExceptions:
          - com.example.BusinessException
    instances:
      userService:
        baseConfig: default

3.2 配置项说明 #

配置项 默认值 说明
maxAttempts 3 最大重试次数
waitDuration 500ms 重试等待时间
enableExponentialBackoff false 是否启用指数退避
exponentialBackoffMultiplier 2 指数退避乘数
enableRandomizedWait false 是否启用随机等待
randomizedWaitFactor 0.5 随机等待因子
retryExceptions - 触发重试的异常
ignoreExceptions - 忽略的异常

四、退避算法 #

4.1 固定间隔 #

yaml
resilience4j:
  retry:
    configs:
      default:
        maxAttempts: 3
        waitDuration: 1s
text
第1次 ──► 等待1s ──► 第2次 ──► 等待1s ──► 第3次

4.2 指数退避 #

yaml
resilience4j:
  retry:
    configs:
      default:
        maxAttempts: 3
        waitDuration: 500ms
        enableExponentialBackoff: true
        exponentialBackoffMultiplier: 2
text
第1次 ──► 等待500ms ──► 第2次 ──► 等待1000ms ──► 第3次

4.3 随机退避 #

yaml
resilience4j:
  retry:
    configs:
      default:
        maxAttempts: 3
        waitDuration: 500ms
        enableRandomizedWait: true
        randomizedWaitFactor: 0.5
text
第1次 ──► 等待250ms~750ms ──► 第2次 ──► 等待250ms~750ms ──► 第3次

五、异常处理 #

5.1 指定重试异常 #

yaml
resilience4j:
  retry:
    configs:
      default:
        maxAttempts: 3
        retryExceptions:
          - java.io.IOException
          - java.net.SocketTimeoutException
          - org.springframework.web.client.HttpServerErrorException

5.2 忽略异常 #

yaml
resilience4j:
  retry:
    configs:
      default:
        maxAttempts: 3
        ignoreExceptions:
          - com.example.BusinessException
          - com.example.ValidationException

5.3 自定义异常判断 #

java
@Configuration
public class RetryConfig {

    @Bean
    public Retry userServiceRetry() {
        RetryConfig config = RetryConfig.custom()
            .maxAttempts(3)
            .waitDuration(Duration.ofMillis(500))
            .retryOnException(throwable -> {
                if (throwable instanceof BusinessException) {
                    return false;
                }
                return true;
            })
            .build();
        
        return Retry.of("userService", config);
    }
}

六、编程式使用 #

6.1 创建重试器 #

java
@Configuration
public class RetryConfig {

    @Bean
    public Retry userServiceRetry() {
        RetryConfig config = RetryConfig.custom()
            .maxAttempts(3)
            .waitDuration(Duration.ofMillis(500))
            .enableExponentialBackoff()
            .exponentialBackoffMultiplier(2)
            .build();
        
        return Retry.of("userService", config);
    }
}

6.2 使用重试器 #

java
@Service
public class UserService {

    @Autowired
    private Retry retry;

    public User getUser(Long id) {
        Supplier<User> supplier = Retry.decorateSupplier(
            retry,
            () -> userClient.getUserById(id)
        );
        
        return Try.ofSupplier(supplier)
            .recover(throwable -> createDefaultUser(id))
            .get();
    }
}

6.3 异步重试 #

java
@Service
public class UserService {

    @Autowired
    private Retry retry;

    public CompletableFuture<User> getUserAsync(Long id) {
        Supplier<CompletableFuture<User>> supplier = Retry.decorateCompletionStage(
            retry,
            Executors.newFixedThreadPool(10),
            () -> CompletableFuture.supplyAsync(() -> userClient.getUserById(id))
        );
        
        return supplier.get();
    }
}

七、组合使用 #

7.1 重试+熔断 #

java
@Service
public class UserService {

    @Retry(name = "userService")
    @CircuitBreaker(name = "userService", fallbackMethod = "fallback")
    public User getUser(Long id) {
        return userClient.getUserById(id);
    }

    private User fallback(Long id, Throwable t) {
        return createDefaultUser(id);
    }
}

7.2 重试+限流 #

java
@Service
public class UserService {

    @RateLimiter(name = "userService")
    @Retry(name = "userService", fallbackMethod = "fallback")
    public User getUser(Long id) {
        return userClient.getUserById(id);
    }

    private User fallback(Long id, Throwable t) {
        return createDefaultUser(id);
    }
}

八、事件监听 #

8.1 配置事件监听 #

java
@Configuration
public class RetryEventConfig {

    @Bean
    public RetryEventListener retryEventListener(RetryRegistry registry) {
        registry.getAllRetries().forEach(retry -> {
            retry.getEventPublisher()
                .onRetry(event -> log.info("Retry: {}", event))
                .onSuccess(event -> log.info("Retry success: {}", event))
                .onError(event -> log.error("Retry error: {}", event));
        });
        
        return new RetryEventListener();
    }
}

8.2 事件类型 #

事件类型 说明
RetryOnRetryEvent 重试事件
RetryOnSuccessEvent 重试成功
RetryOnErrorEvent 重试失败

九、最佳实践 #

9.1 生产环境配置 #

yaml
resilience4j:
  retry:
    configs:
      default:
        maxAttempts: 3
        waitDuration: 500ms
        enableExponentialBackoff: true
        exponentialBackoffMultiplier: 2
        retryExceptions:
          - java.io.IOException
          - java.net.SocketTimeoutException
          - org.springframework.web.client.HttpServerErrorException
        ignoreExceptions:
          - com.example.BusinessException
    instances:
      userService:
        baseConfig: default
      orderService:
        baseConfig: default
        maxAttempts: 5

9.2 注意事项 #

注意点 说明
幂等性 重试操作必须是幂等的
重试次数 避免过多重试
退避策略 使用指数退避避免雪崩
异常分类 区分可重试和不可重试异常

十、总结 #

10.1 核心要点 #

要点 说明
重试次数 maxAttempts控制
退避策略 固定/指数/随机
异常处理 retryExceptions/ignoreExceptions
幂等性 重试操作必须幂等

10.2 下一步 #

现在你已经掌握了重试机制的使用,接下来让我们学习 配置中心,了解如何管理微服务配置!

最后更新:2026-03-28