2020-03-09

MQ如何确保消息不会丢失


1.检测消息丢失的方法

    1.分布式链路追踪系统,使用类似的追踪系统可以很方便地追踪每一条消息。

    2.我们可以利用消息队列的有序性来验证是否有消息丢失。原理非常简单,在 Producer 端,我们给每个发出的消息附加一个连续递增的序号,然后在 Consumer 端来检查这个序号的连续性。

需要注意:

    像 Kafka 和 RocketMQ 这样的消息队列,它是不保证在 Topic 上的严格顺序的,只能保证分区(队列)上的消息是有序的,所以我们在发消息的时候必须要指定分区,并且,在每个分区单独检测消息序号的连续性

2.确保消息可靠传递

整个消息从生产到消费的过程中,哪些地方可能会导致丢消息,以及应该如何避免消息丢失。

分三个阶段:

    1.生产阶段

        在生产阶段,消息队列通过最常用的请求确认机制,来保证消息的可靠传递。你在编写发送消息代码时,需要注意,正确处理返回值或者捕获异常,就可以保证这个阶段的消息不会丢失

    2.存储阶段

        在存储阶段正常情况下,只要 Broker 在正常运行,就不会出现丢失消息的问题,但是如果 Broker 出现了故障,比如进程死掉了或者服务器宕机了,还是可能会丢失消息的。如果对消息的可靠性要求非常高,可以通过配置 Broker 参数来避免因为宕机丢消息。        

        对于单个节点的 Broker,需要配置 Broker 参数,在收到消息后,将消息写入磁盘后再给 Producer 返回确认响应,这样即使发生宕机,由于消息已经被写入磁盘,就不会丢失消息,恢复后还可以继续消费。例如,在 RocketMQ 中,需要将刷盘方式 flushDiskType 配置为 SYNC_FLUSH 同步刷盘。

        Broker 是由多个节点组成的集群,需要将 Broker 集群配置成:至少将消息发送到 2 个以上的节点,再给客户端回复发送确认响应。这样当某个 Broker 宕机时,其他的 Broker 可以替代宕机的 Broker,也不会发生消息丢失。

    3.消费阶段

        消费阶段采用和生产阶段类似的确认机制来保证消息的可靠传递。需要注意的是,不要在收到消息后就立即发送消费确认,而是应该在执行完所有消费业务逻辑之后,再发送消费确认。

总结:

    1.在生产阶段,你需要捕获消息发送的错误,并重发消息。

    2.在存储阶段,你可以通过配置刷盘和复制相关的参数,让消息写入到多个副本的磁盘上,来确保消息不会因为某个 Broker 宕机或者磁盘损坏而丢失。

    3.在消费阶段,你需要在处理完全部消费业务逻辑之后,再发送消费确认。

做到以上三个阶段,每个阶段都需要正确的编写代码并且设置正确的配置项,才能配合消息队列的可靠性机制,确保消息不会丢失。

来源:(李玥-消息队列高手)学习总结

你可能感兴趣的:(2020-03-09)