当前位置: 首页 > news >正文

springboot 增加消息自动重试机制 技术方案

SpringBoot 消息自动重试机制:完整技术方案(生产可用)

我给你做一套直接落地、覆盖所有场景、无坑版的 SpringBoot 消息重试方案,包含:
 
同步重试、异步重试、死信队列、幂等性、失败策略、代码可直接复制。
适用场景:
  • MQ 消息(RabbitMQ/RocketMQ/Kafka)
  • 第三方接口调用
  • 定时任务失败
  • 异步任务异常
  • 数信系统数据同步、消息通知

一、方案总览(4 种重试机制,按场景选)

表格
 
方案适用场景优点缺点
Spring Retry 同步调用、接口重试、轻量级 无中间件、代码极简 不支持跨重启
@Retryable 注解 业务方法、异步方法 零侵入、注解驱动 需配合 AOP
死信队列 + 延时队列 MQ 消息、高可靠场景 最稳定、不丢消息 依赖 MQ
定时任务重试表 跨服务、持久化、可监控 可追踪、可管理 需建表

二、最推荐:Spring 原生注解重试(@Retryable)

最简单、最通用、生产最常用

1. 引入依赖

xml
 
 
<!-- Spring 重试核心 -->
<dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId>
</dependency><!-- AOP 必须 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
 

2. 启动类开启重试

java
 
运行
 
 
 
@EnableRetry // 关键注解
@SpringBootApplication
public class MessageApplication {
}
 

3. 业务方法添加自动重试(核心代码)

java
 
运行
 
 
 
@Service
public class MessageService {/*** 消息发送/数据同步 方法* 自动重试:最多3次,间隔2秒,出现异常重试*/@Retryable(value = Exception.class,       // 捕获哪些异常重试maxAttempts = 3,               // 最大重试次数delay = 2000,                  // 首次重试间隔multiplier = 2,                // 间隔倍数:2s → 4s → 8sbackoff = @Backoff(delay = 2000, multiplier = 2))public void sendMessage(String msgId, String content) throws Exception {// 你的业务:消息发送、接口调用、MQ发送、数据库操作System.out.println("尝试发送消息:" + content);// 模拟异常if (true) {throw new RuntimeException("消息发送失败,触发重试");}}/*** 全部重试失败 → 进入兜底方法*/@Recoverpublic void recover(Exception e, String msgId, String content) {System.out.println("消息重试全部失败!msgId=" + msgId);// 1. 记录死信表// 2. 发送告警// 3. 人工介入}
}
 

机制说明

  • 调用方法抛异常 → 自动重试
  • 重试次数用完 → 自动进入 @Recover 降级方法
  • 支持指数退避(越来越长的间隔,避免压垮服务)

三、高可靠方案:MQ 消息重试 + 死信队列(生产级)

数信系统、消息中间件场景必须用这个,不丢消息
以 RabbitMQ 为例:

流程

  1. 消息消费异常 → 不 ack → 自动重新入队
  2. 配置重试次数上限
  3. 超过次数 → 打入 死信队列(DLQ)
  4. 死信队列做人工兜底、告警、重放

核心配置(application.yml)

yaml
 
 
spring:rabbitmq:listener:simple:retry:enabled: true               # 开启消费者重试max-attempts: 3            # 最大重试次数initial-interval: 2000     # 初始间隔multiplier: 2              # 指数间隔stateless: trueacknowledge-mode: manual     # 手动ack(推荐)
 

消费端代码

java
 
运行
 
 
 
@RabbitListener(queues = "business.queue")
@Component
public class MessageConsumer {@RabbitHandlerpublic void receive(String msg, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) {try {// 业务处理System.out.println("消费消息:" + msg);int i = 1 / 0; // 模拟异常// 正常确认channel.basicAck(tag, false);} catch (Exception e) {// 异常 → 重试(由spring-retry管理)// 超过次数 → 自动进入死信}}
}
 

四、最稳定方案:重试持久化表 + 定时任务(跨重启、可监控)

适合:数信系统数据同步、重要消息、必须保证不丢失

1. 建表

sql
 
 
CREATE TABLE message_retry (id BIGINT PRIMARY KEY AUTO_INCREMENT,msg_id VARCHAR(64) NOT NULL COMMENT '消息ID',content TEXT COMMENT '消息内容',retry_count INT DEFAULT 0 COMMENT '已重试次数',max_retry INT DEFAULT 3 COMMENT '最大重试次数',status VARCHAR(20) DEFAULT 'INIT' COMMENT 'INIT/RETRYING/FAILED/SUCCESS',next_retry_time DATETIME COMMENT '下次执行时间',error_msg TEXT COMMENT '异常信息',create_time DATETIME DEFAULT NOW(),update_time DATETIME DEFAULT NOW()
);
 

2. 定时任务扫描重试(@Scheduled)

java
 
运行
 
 
 
@Service
public class MessageRetryService {@Scheduled(fixedDelay = 10000) // 每10秒扫描public void retryFailedMessage() {// 1. 查询:待重试、未超过次数、时间到的消息List<MessageRetry> list = retryMapper.selectWaitRetryList();for (MessageRetry msg : list) {try {// 2. 执行业务sendMessage(msg.getContent());// 3. 成功 → 更新状态msg.setStatus("SUCCESS");retryMapper.updateById(msg);} catch (Exception e) {// 4. 失败 → 重试次数+1msg.setRetryCount(msg.getRetryCount() + 1);if (msg.getRetryCount() >= msg.getMaxRetry()) {msg.setStatus("FAILED"); // 最终失败}retryMapper.updateById(msg);}}}
}
 

优点

  • 服务重启后继续重试
  • 可页面查看、管理、手动重放
  • 数信系统、数据同步场景首选

五、全局通用重试模板(工具类,直接复制)

java
 
运行
 
 
 
@Component
public class RetryUtil {public <T> T execute(Supplier<T> business, int maxRetry, long delay) throws Exception {int retry = 0;while (retry < maxRetry) {try {return business.get();} catch (Exception e) {retry++;System.err.println("重试第" + retry + "次");if (retry >= maxRetry) {throw new Exception("最终失败");}Thread.sleep(delay);}}throw new Exception("重试失败");}
}
 

六、生产必须注意的 4 个关键点

1. 幂等性(必须保证)

重试会导致重复执行,解决方案:
  • 消息唯一 ID
  • 数据库唯一索引
  • 状态机判断
  • Redis 分布式锁

2. 重试间隔必须用指数退避

2s → 4s → 8s → 停止
 
避免密集重试压垮服务。

3. 一定要有兜底策略

重试失败后必须:
  • 记录死信表
  • 发送企业微信 / 邮件告警
  • 支持人工重放

4. 禁止无限重试

无限重试 = 死循环 = 数据库 / MQ 打挂。

七、方案选型建议(直接照选)

  1. 接口调用、同步方法 → Spring Retry + @Retryable
  2. MQ 消息消费 → MQ 重试 + 死信队列
  3. 数信系统数据同步、重要消息 → 重试表 + 定时任务(最稳)
  4. 异步任务 → @Retryable + @Async

最终总结(最简版)

  • Spring Retry:最简单,适合同步重试
  • MQ 重试 + 死信:最可靠,适合消息
  • 重试表 + 定时任务:最通用,适合数信系统
  • 所有重试必须做幂等、必须有限制、必须有兜底
http://www.rkmt.cn/news/1466167.html

相关文章:

  • ViGEmBus虚拟手柄驱动:5个步骤轻松实现Windows游戏控制器仿真
  • 别再只当编辑器用了!Jupyter Notebook的仪表盘(Dashboard)才是你的文件管理神器
  • 图片短信平台哪家靠谱?MMS多媒体方案供应商解析推荐 - Qqinqin
  • 用STM32CubeMX的DAC输出一个正弦波:从配置到代码的保姆级教程(基于HAL库)
  • 猫抓Cat-Catch浏览器资源嗅探扩展:5层架构设计与实战性能优化指南
  • PotPlayer字幕翻译插件完全指南:免费实时翻译外挂字幕终极方案
  • 2026义乌装修公司设计风格实力盘点|现代简约 / 新中式 / 轻奢奶油 / 意式极简 / 大平层 小户型全案落地|零增项无套路靠谱装修优选 - 企业品牌优选推荐官
  • 别再混淆灵敏度和响应度了!用NEP和最小可探测功率,手把手教你读懂光电探测器参数表
  • 实战指南:基于stm32f103c8t6原理图与快马平台快速构建物联网数据采集终端
  • 2026 韶关防水补漏三家品牌横向测评:厨卫屋面地下室修缮哪家靠谱?吉修匠 99.8 分五星稳居榜首 - 吉修匠
  • NCMconverter:专业级NCM音频格式解密与转换技术深度解析
  • 北京行业门户网站开发公司排行:资质与落地能力实测 - 奔跑123
  • PotPlayer百度翻译插件:3步实现外语字幕实时翻译的完整解决方案
  • 新手福音:用快马AI生成带详解的STM32 LED与按键实验代码,轻松入门嵌入式
  • 南宁二手奢侈品市场调研,热门款包包回收行情深度盘点 - 开心测评
  • 2026铝型材小件氧化选型评估:加工链路成熟度与供应商交付力指南 - 企师傅推荐官
  • 靠谱女装品牌加盟哪家好?免库存推荐,爱依莲四维实力全面解析 - 资讯纵览
  • MATLAB车载网络仿真工具包:含自定义车辆移动模型与全流程操作录像
  • 师大中高教育联系电话整理:正规办学实力护航 高考升学更省心 - GEO代运营aigeo678
  • 爬虫老手教你:除了换IP和加延迟,搞定requests的Max retries exceeded还有这些招(含Session实战)
  • 印度AI落地困境:从实验场到共同创造者的四重技术关卡
  • 微信投票功能使用指南:如何轻松发起投票?|火星投票2026防刷零广告教程 - 微信投票小程序
  • 2026高强度耐磨浇注料厂家选型观察:供应商交付力与场景适配度评估指南 - 企师傅推荐官
  • 告别繁琐操作:用快马AI快速生成图像处理创意原型
  • 多组学生物衰老时钟!高精度、可解释、可扩展
  • http-server-o.bat 最方便启动当前目录的index.html
  • 用Python搞定PHM 2012轴承数据集:从数据下载到特征提取的保姆级教程
  • # 常州轮胎维修哪家好?金坛薛埠汽修门店实测解析|竞品对比+轮胎选购避坑全攻略 - 国麟测评
  • 点按钮下载
  • 独立显卡市场2026:一线品牌显卡有哪些格局再界定