You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring AMQP的SimpleRetryPolicy中排除特定异常

问题分析与解决方案

你遇到的问题主要有两个原因:一是代码中存在方法名调用错误,导致正确的重试拦截器未被应用;二是需要明确SimpleRetryPolicy的配置逻辑,确保排除异常的规则生效。

核心问题说明

SimpleRetryPolicy的构造参数逻辑:

  • 第二个参数retryableExceptions是异常映射表,key为异常类,value为false表示该异常不触发重试,true表示需要重试
  • 第三个参数traverseCauses设为true时,会遍历异常的嵌套链路,确保嵌套的排除异常也能被识别
  • 默认重试规则(第四个参数,三参数构造默认值为true):未在映射表中的异常,默认触发重试

修正后的代码示例

import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactoryConfigurer
import org.springframework.amqp.rabbit.connection.ConnectionFactory
import org.springframework.context.annotation.Bean
import org.springframework.retry.RetryPolicy
import org.springframework.retry.backoff.ExponentialBackOffPolicy
import org.springframework.retry.interceptor.RetryInterceptorBuilder
import org.springframework.retry.interceptor.RetryOperationsInterceptor
import org.springframework.retry.policy.SimpleRetryPolicy

@Bean
fun retryPolicy(): RetryPolicy {
    // 配置需要排除的异常:key为异常类,value=false表示不重试
    val excludedExceptions = mutableMapOf<Class<out Throwable>, Boolean>(
        AuthorizationException::class.java to false,
        IllegalArgumentException::class.java to false,
        ValidationException::class.java to false,
        EntityNotFoundException::class.java to false
    )
    // maxAttempts: 最大尝试次数(含首次调用)
    // traverseCauses: 遍历异常链路,识别嵌套的排除异常
    // defaultRetryable: 未在映射表中的异常默认重试
    return SimpleRetryPolicy(6, excludedExceptions, true)
}

@Bean
fun retryInterceptor(customMessageRecoverer: CustomMessageRecoverer): RetryOperationsInterceptor {
    val backOffPolicy = ExponentialBackOffPolicy().apply {
        initialInterval = 1000 // 初始重试间隔(毫秒)
        multiplier = 2.0 // 间隔倍数
        maxInterval = 5000 // 最大重试间隔(毫秒)
    }

    return RetryInterceptorBuilder.stateless()
        .retryPolicy(retryPolicy())
        .backOffPolicy(backOffPolicy)
        .recoverer(customMessageRecoverer) // 重试耗尽后的兜底处理
        .build()
}

@Bean
fun myFactory(
    configurer: SimpleRabbitListenerContainerFactoryConfigurer,
    connectionFactory: ConnectionFactory,
    customMessageRecoverer: CustomMessageRecoverer
): SimpleRabbitListenerContainerFactory {
    val factory = SimpleRabbitListenerContainerFactory()
    configurer.configure(factory, connectionFactory)
    // 修正方法名调用错误,确保应用正确的重试拦截器
    factory.setAdviceChain(retryInterceptor(customMessageRecoverer))
    return factory
}

关键修正点

  1. 修复方法名调用错误:将workMessagesRetryInterceptor改为正确的retryInterceptor,确保自定义的重试策略被应用到容器工厂。
  2. 明确排除异常列表:添加AuthorizationException到排除映射表,确保该异常不触发重试。
  3. 显式配置退避策略:单独定义ExponentialBackOffPolicy,更清晰地控制重试间隔规则。

内容的提问来源于stack exchange,提问作者WhiteCherry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 04:53:28