如何在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 }
关键修正点
- 修复方法名调用错误:将
workMessagesRetryInterceptor改为正确的retryInterceptor,确保自定义的重试策略被应用到容器工厂。 - 明确排除异常列表:添加
AuthorizationException到排除映射表,确保该异常不触发重试。 - 显式配置退避策略:单独定义
ExponentialBackOffPolicy,更清晰地控制重试间隔规则。
内容的提问来源于stack exchange,提问作者WhiteCherry
相关产品推荐
相关产品推荐

