Spring Boot中SqsTemplate发送消息的异常处理方法咨询
Spring Cloud AWS SQS 消息发送异常处理(适配Spring Boot 3.2.1 + spring-cloud-aws-starter-sqs 3.1.0)
在你使用的版本中,SQS消息发送失败时会抛出Spring Cloud AWS封装的SqsException,以及AWS SDK底层的SdkClientException(客户端侧问题,如网络超时、配置错误)、SdkServiceException(服务端返回错误,如队列不存在、权限不足、限流)等异常。以下是几种实用的异常处理方案:
一、基础捕获处理:直接try-catch
针对单条消息发送,直接捕获对应异常并做业务适配处理:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.core.exception.SdkClientException; import software.amazon.awssdk.core.exception.SdkServiceException; import io.awspring.cloud.sqs.SqsException; import io.awspring.cloud.sqs.operations.SqsTemplate; // 业务发送类示例 public class SqsMessageSender { private static final Logger log = LoggerFactory.getLogger(SqsMessageSender.class); private final SqsTemplate sqsTemplate; public SqsMessageSender(SqsTemplate sqsTemplate) { this.sqsTemplate = sqsTemplate; } public void sendMessage(String message) { try { sqsTemplate.send(sqsSendOptions -> sqsSendOptions .queue("myqueue") .payload(message) ); log.info("消息发送成功"); } catch (SqsException e) { // 处理Spring Cloud AWS封装的顶层SQS异常 log.error("SQS消息发送失败,队列:myqueue,错误详情:{}", e.getMessage(), e); // 业务降级逻辑:存入本地重试表、触发告警通知等 } catch (SdkClientException e) { // 客户端侧异常:网络中断、配置错误等 log.error("SQS客户端通信失败,网络或配置异常:{}", e.getMessage(), e); } catch (SdkServiceException e) { // 服务端返回的错误:可根据状态码做针对性处理 log.error("SQS服务端返回错误,状态码:{},错误信息:{}", e.statusCode(), e.getMessage(), e); // 例如:404时检查队列是否存在,403时检查权限配置 } } }
二、客户端层面自动重试
通过配置让AWS SDK客户端自动处理可重试的异常(如网络超时、服务端5xx错误),无需手动写重试逻辑:
在application.yml中添加配置:
spring: cloud: aws: sqs: client: retry: max-attempts: 3 # 最大重试次数 mode: STANDARD # 指数退避重试模式 backoff: base-delay: 1000ms # 初始重试间隔 max-delay: 5000ms # 最大重试间隔
三、业务层面重试:Spring Retry
如果需要更灵活的重试策略(比如针对特定异常、自定义重试间隔),可以结合Spring Retry:
- 添加Maven依赖:
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
- 在启动类上开启重试支持:
import org.springframework.retry.annotation.EnableRetry; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableRetry public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
- 在发送方法上标注重试注解:
import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Recover; import org.springframework.retry.annotation.Retryable; @Retryable( value = {SqsException.class, SdkClientException.class}, // 指定需要重试的异常类型 maxAttempts = 3, // 最大重试次数 backoff = @Backoff(delay = 1000, multiplier = 2) // 指数退避:第一次1s,第二次2s,第三次4s ) public void sendMessageWithRetry(String message) { sqsTemplate.send(sqsSendOptions -> sqsSendOptions .queue("myqueue") .payload(message) ); } // 重试失败后的兜底处理方法 @Recover public void handleRetryFailure(SqsException e, String message) { log.error("重试3次后仍发送失败,消息内容:{}", message, e); // 最终降级逻辑:写入死信表、通知运维等 }
内容的提问来源于stack exchange,提问作者Mister_L
相关产品推荐
相关产品推荐

