RabbitMQ经典三问

RabbitMQ如何保证消息不会丢失?

可能会造成消息丢失的原因

  • 生产者方面,当生产者发送消息到 Broker 时,由于网络问题或者自身问题没有达到
  • 消息到达Broker,但是当 Broker 持久化的时候,RabbitMQ宕机
  • 消费者方面,消费者在接收消息时,出现宕机或者自身服务问题导致消息没收到

解决方法

  • 生产端要做 confirm 机制, 当消息发送给 Broker 时,Broker都要告诉生产者。如果失败了,可以将失败的消息保存到数据库中,采用定期扫描的方式尝试重新推送。
  • 消费端要做 手动ack 机制,当消费者消费成功之后,要告诉RabbitMQ删除队列中的消息。
    • 这样可能还存在一个问题,就是消费端返回 ack 时,突然宕机,由于消费者消费完了,但是队列中的消息还存在,就有可能造成 重复消费 的问题

RabbitMQ 如何避免重复消费?

造成重复消费的原因

  • 生产者:重复推送一条数据,比如:多次调用 Controller 接口,没有做接口幂等性导致
  • MQ端:消费者消费成功,响应 ack 时,MQ挂掉了,导致MQ认为还未消费这条数据,当MQ恢复后,继续推送这条数据导致重复消费
  • 消费端:消费者消费完,正准备响应 ack 时,消费者挂掉了 ,消费者恢复之后,MQ仍然认为没有消费成功。

解决方法

  • 使用数据库唯一约束

但是它局限性比较大,仅能在数据库新增时生效,并且性能较低

  • 在生产端将接口设计成幂等性, 防止重复推送同一条数据
  • 使用防重表(Redis/MySQL), 插入消费记录

当消费者开始消费的时候,先在防重表 中插入一条记录,记录当前记录的状态为消费中

  • 如果能插入成功,说明这条消息还没有消费过,去正常执行业务代码即可。
    • 当业务代码执行失败时,将该条记录在 防重表 中删除,继续重试
  • 如果插入失败,说明这条消息正在消费中或者已经消费过,但是由于某些原因导致未删除记录。
    • 此时在判断这条消息是否已经消费过,消费过则返回成功结束,没有消费过,可以利用延时队列进行重试!

可以利用Redis防重表 中插入一条记录时,设置一个过期时间,为了避免在执行完业务代码、更新业务状态时出现异常而导致重复消费。

并且还可以记录一个 消费次数 的字段 , 当一条消息被多次消费 仍然不成功时,可以记录到日志中,由具体的开发人员分析到底是什么原因,具体分析!

RabbitMQ如何解决消息堆积问题?

产生消息堆积的原因

  • 消费者宕机积压

  • 消费者消费能力不足积压

  • 发送者发送流量太大

解决方法

  • 简化消费者的逻辑,减少耗时,提高消费速度
  • 如果存在无法处理的消息,使用死信队列,防止堵塞
  • 上线更多的消费者,进行正常消费
相关推荐
微三云 - 廖会灵 (私域系统开发)20 小时前
电商系统微服务拆分实战:从单体到Spring Cloud的分布式事务踩坑与补偿方案
分布式·spring cloud·微服务
ACP广源盛139246256731 天前
破局 PCIe 4.0 交换瓶颈@ACP#IX8024 / ASM58024参数及应用对比
大数据·人工智能·分布式·嵌入式硬件
淡然的煎蛋1 天前
开始使用RabbitMQ
分布式·rabbitmq·ruby
笨鸟先飞的橘猫2 天前
skynet——分布式支持
分布式·skynet
ACP广源盛139246256732 天前
GSV6155 @ACP#工业车规 DP1.4 重定时器 Retimer
大数据·人工智能·分布式·嵌入式硬件
ACP广源盛139246256732 天前
GSV2221@ACP# DP1.4 MST 多流显示转换芯片国产工业多屏
大数据·人工智能·分布式·嵌入式硬件·spark
sukioe2 天前
从 0 到 1 构建城市公共设施智能报修与派单系统:FastAPI + Vue3 + RabbitMQ + Redis Geo + AI 工作流实践
redis·rabbitmq·fastapi
ACP广源盛139246256732 天前
GSV2231@ACP# 增强型 8K MST 多屏扩展芯片
大数据·人工智能·分布式·嵌入式硬件
虚心的百褶裙2 天前
远程调用服务架构设计及zookeeper技术详解(下篇)
分布式·zookeeper·云原生
清晨曦月2 天前
【从零构建分布式在线评测系统】二、Judge0服务器上的心跳程序
运维·服务器·分布式