MQ消息丢失
- 消息丢失可能出现在三个场景:生产者发送消息时,消息中间件丢失消息,消费者消息丢失
生产者消息发送消息丢失
产生的原因:消息发出后,网路问题,消息中间件没有收到信息
解决方案:
开启RabbitMQ的事务机制
try {
channel.txSelect();
channel.basicPublish("", QUEUE_NAME, null, (msg).getBytes());
channel.txCommit();
System.out.println("消息发送成功");
} catch (Exception e) {
channel.txRollback();
System.out.println("消息已经回滚");
}
开启Confirm模式
- Confirm模式有三种模式:普通确认模式,异步确认模式,批量确认模式
普通确认模式
- 普通Confirm,发送一条,确认一条
- 不足:效率较低
channel.confirmSelect();
channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
if (channel.waitForConfirms()) {
System.out.println("消息发送成功" );
}
批量确认模式
- 批量发送信息
- 不足:批次发送的数量不确定,如果批量发送中有一条数据出现异常,所有消息要进行补偿重发
try {
channel.confirmSelect();
for (int i = 0; i < 5; i++) {
channel.basicPublish("", QUEUE_NAME, null, (msg +"-"+ i).getBytes());
}
channel.waitForConfirmsOrDie();
System.out.println("消息发送完毕,批量确认成功");
} catch (Exception e) {
e.printStackTrace();
}
异步确认模式
final SortedSet<Long> confirmSet = Collections.synchronizedSortedSet(new TreeSet<Long>());
channel.addConfirmListener(new ConfirmListener() {
public void handleNack(long deliveryTag, boolean multiple) throws IOException {
System.out.println("Broker未确认消息,标识:" + deliveryTag);
if (multiple) {
confirmSet.headSet(deliveryTag + 1L).clear();
} else {
confirmSet.remove(deliveryTag);
}
}
public void handleAck(long deliveryTag, boolean multiple) throws IOException {
System.out.println(String.format("Broker已确认消息,标识:%d,多个消息:%b", deliveryTag, multiple));
if (multiple) {
confirmSet.headSet(deliveryTag + 1L).clear();
} else {
confirmSet.remove(deliveryTag);
}
System.out.println("未确认的消息:"+confirmSet);
}
});
channel.confirmSelect();
for (int i = 0; i < 10; i++) {
long nextSeqNo = channel.getNextPublishSeqNo();
channel.basicPublish("", QUEUE_NAME, null, (msg +"-"+ i).getBytes());
confirmSet.add(nextSeqNo);
}
System.out.println("所有消息:"+confirmSet);
事务模式和Confirm模式的比较
- 性能方面:事务模式是同步进行,流程会阻塞,吞吐率会下降,比较损耗性能;confirm模式正好相反,异步执行,因此不会阻塞流程;
消息中间件发送消息过程中消息丢失
产生的原因:RabbitMQ接收到信息后出现故障,并且消息还没来得及发送给消费者,且没有进行持久化
解决方案:
@Bean("GpQueue")
public Queue GpQueue() {
return new Queue("GP_TEST_QUEUE", true, false, false, new HashMap<>());
}
@Bean("GpExchange")
public DirectExchange exchange() {
return new DirectExchange("GP_TEST_EXCHANGE", true, false, new HashMap<>());
}
消费者接收消息和处理消息过程中消息丢失
产生的原因:消费者信息处理失败的情况下,触发了自动ACK提交,出现了数据未消费成功却返回ack信息
解决方案:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
2020-08-17 vue-router.esm.js: Error: "Loading chunk 0 failed"