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

理解消息队列的持久性,可靠性,幂等性

持久性

一些下单任务,例如付完钱后异步下单,为啥我们主流都是使用mq来做异步,而不是使用线程池来做异步呢?明明都能做异步

因为如果我们的Java程序宕机了,那么我们的异步任务没完成完,那就直接结束了

如果我们使用mq的话,它是Broker,它有持久化功能,文件可以存储到MQ内部,本地文件持久化

这样子我们就能重试,保证消息消费


可靠性

mq有重试机制,如果消息发送失败的话我们可以重试,而用线程池这种的话要写一对冗余的代码

我们保证消息能成功发送

可靠性体现在三个地方

确保生产者发送给Broker

失败场景:网络波动或者mq宕机等,导致发送不过去

确保Broker发送给消费者

失败场景:网络波动或者mq宕机等,导致发送不过去

确保保证消费者能成功消费到消息

默认:发送到消费者mq就标记消费成功,也就是成功发送到消费者就直接ack

失败场景:我们可能消息队列发送给消费者成功,但是java程序没执行完代码就宕机的,但是此时我的消息队列已经发送消息了,所以它会结束表示成功消费,但是其实我们java程序没运行完,本质上还是消费失败。

所以我们有一个手动ack机制,也就是我们执行完,再返回一个ack告诉消息队列我们发送成功了

不然我们就重试3次(代码要自己写)

我拿RabbitMq举例子,可以看一下我的其他文章

RabbitMq手动ack的超简单案例+Confirm和Return机制的配置和使用_rabbitmq 手动ack-CSDN博客


幂等性

重复消费问题

幂等性就是保证消息的唯一性,防止消息被重复消费

可能因为网络故障波动或者其他原因,导致我们的mq重复发送多次请求给消费者,导致我们的消费者重复消费。

如果是下单那么我们的单号可能有重复的5个,这样子明显是不行的

解决方案

我们要弄消息的唯一ID(唯一标识)

例如把消息的唯一标识改成UUID+时间戳,那么怎么样都不会遇到ID相同的情况

为什么要这样弄呢?

我拿RabbitMq举例子,RabbitMq的消息的唯一ID是通过队列名,交换机名和消息内容生成的。

那我们发送消息内容相同,那么我们的自动生成的ID不就一样了?

所以我们要改一下我们的ID生成策略

然后我们把这个ID存到Redis里面去,每次消费前去判断Redis里面是否存在这个ID。

如果有那么就消费过了,我们不执行,防止重复下单。

如果没有,那么就是我们没消费过,我们直接下单就行了。

这样子就保证了消息的幂等性


这三个性质是共通的,可以延伸到其他的消息队列,例如Kafka和RocketMq


http://www.mrgr.cn/news/1686.html

相关文章:

  • 修改Docker的默认网段
  • C语言 - 构造类型
  • C语言是真男人就挺过100回合
  • 产品经理基础知识
  • 华为 OLT 添加 ONU 配置 (SNMP管理模式)
  • java之责任链模式
  • Qt框架学习03——对象树模型
  • ETAS工具链自动化实战指南<一>
  • 网站自动化锚文本的实现逻辑
  • 【C++ 面试 - 面向对象】每日 3 题(一)
  • 【ubuntu24.04】错误:8llvm 由于没有公钥:无法验证下列签名 NO_PUBKEY
  • 软考软件设计师-备考须知
  • 恒创科技:云服务器的备份和快照哪个更好?
  • Python抓取远程图片到本地
  • 05--kubernetes组件与安装
  • python爬虫代理IP实战
  • 安卓中携程和线程的区别。携程是指什么?
  • 余弦相似度详解及应用案例
  • DNS域名解析服务
  • 基于Spring boot的名城小区物业管理系统