Skip to content

Latest commit

 

History

History
53 lines (28 loc) · 3.14 KB

mq-msg-lost.md

File metadata and controls

53 lines (28 loc) · 3.14 KB

MQ 如何处理消息丢失

消息的发送过程

2021-5-18T223009.png

  • 生产阶段:Producer 新建消息,然后通过网络将消息投递给 MQ Broker

  • 存储阶段:消息将会存储在 Broker 端磁盘中

  • 消费阶段:Consumer 将会从 Broker 拉取消息

以上任一阶段都可能会丢失消息,我们只要找到这三个阶段丢失消息原因,采用合理的办法避免丢失,就可以彻底解决消息丢失的问题。

生产阶段

生产者(Producer) 通过网络发送消息给 Broker,当 Broker 收到之后,将会返回确认响应信息给 Producer。所以生产者只要接收到返回的确认响应,就代表消息在生产阶段未丢失。

同步发送

有三种发送方法,同步发送、异步发送、单向发送。我们可以采取同步发送的方式进行发送消息,发消息的时候会同步阻塞等待 Broker 返回的结果,如果没成功,则不会收到 SendResult,这种是最可靠的。其次是异步发送,在回调方法里可以得知是否发送成功。单向发送是最不靠谱的一种发送方式,我们无法保证消息真正可达。

失败重试

发送消息如果失败或者超时了,则会自动重试。默认是重试三次,可以根据API进行更改,比如改为10次:

producer.setRetryTimesWhenSendFailed(10);

存储阶段

MQ 持久化消息分为两种:同步刷盘和异步刷盘。

同步刷盘

默认情况是异步刷盘,Broker 收到消息后会先存到 Cache 里然后立马通知 Producer 成功,然后 Broker 启动异步线程的去持久化到磁盘中,但是 Broker 还没持久化到磁盘就宕机的话,消息就丢失了。同步刷盘的话是收到消息存到 Cache 后并不会通知 Producer 消息已经OK了,而是会等到持久化到磁盘中后才会通知 Producer 消息已经收到了。这也保障了消息不会丢失,但是性能不如异步高。看业务场景取舍。

主从同步复制

即使 Broker 设置了同步刷盘策略,但是 Broker 刷完盘后磁盘坏了,这会导致盘上的消息全部丢失。即使是1主1从,但是 Master 刷完盘后还没来得及同步给 Slave 磁盘就坏了,也会导致消息丢失。所以我们还可以配置不仅是等 Master 刷完盘就通知 Producer,而是等Master 和 Slave 都刷完盘后才去通知 Producer 说消息 OK 了。

消费阶段

消费者从 Broker 拉取消息,然后执行相应的业务逻辑。一旦执行成功,将会返回 ConsumeConcurrentlyStatus.CONSUME_SUCCESS 状态给 Broker。如果 Broker 未收到消费确认响应或收到其他状态,消费者下次还会再次拉取到该条消息,进行重试。这样的方式有效避免了消费者消费过程发生异常,或者消息在网络传输中丢失的情况。

Read More:

面试官再问我如何保证 RocketMQ 不丢失消息,这回我笑了!

udp怎么保证不丢包_从入门到入土(三)RocketMQ 怎么保证的消息不丢失?