各种消息队列经典问题解决方案——消息丢失、顺序消费、消息积压、重复消费

写在开头:

​ 对于消息队列这种中间件来说,只要进入消息队列就会有几个绕不开的问题,比如:消息丢失顺序消费消息积压重复消费 ,下面就来讲解一下市面上比较常见的各个不同的消息队列产品针对这四个问题的解决方案。


1、Kafka
消息丢失解决方案

对于Kafka这个消息队列来说,消息丢失的环节有下面的几个地方:

1、 消息生产者发送消息给Broker的时候数据丢失

2、Broker异常导致Broker中的数据丢失

3、消息消费者消费异常导致消息丢失

只要我们分别针对这几个不同的环节采取相应的措施就可以有效的防止消息发生丢失,下面就来说一下各个环节的措施:

  • 针对 消息生产者发送消息给Broker的时候数据丢失

    ​ 首先我们发送消息的流程是将一个消息发送给指定的topic下的分区中,并且在实际的生产环境下我们 一般都是使用多个Broker来保证Kafka的高可用 的,所以一个Topic有多个分区,并且 同一个Topic下的分区会按照主从模式来设置 ,一般是一个Topic下有一个主分区和多个从分区,并且 不同的Topic下的主分区一般要部署在不同的Broker下 ,来进行隔离。

    ​ 所以我们在消息发送的时候关键的一点就是 :保证我们的消息成功发出去了 。所以在进行发送数据的时候Kafka可以来 使用acks参数 来指定写入语义,其中acks有三个值,分别是 acks=0,acks=1,acks=all

    acks=0 :最简单的生产者写入语义,表示我 只管发送,发送出去之后至于 broker是否收到、是否持久化、是否主从同步不关心。当然这种写入语义是会导致消息丢失的,所以生产中一般不会使用这种写入语义。

    acks=1当Broker中的主分区写入成功的时候就认为发送成功了,不关心从分区是否成功同步消息 。这个写入语义也是会导致消息丢失的,比如主分区写入了但是还没有同步给从分区,这时候主分区宕机了,然后从分区中是没有这个消息的。

    acks=all : 主分区不仅收到了消息并且完成了分区的主从同步 。这个写入语义相比于上面的两个写入语义更加保险,所以在生产中一般推荐使用这个写入语义。当然这种写入语义的性能可能比上面两种写入语义的 性能差 ,毕竟有得必有失嘛。

    ​ 补充 : ISR:与主分区保持了同步的从分区的数量。比如ISR设置为2,代表着与主分区完成了同步的从分区至少有2个,如果少于两个消息就会发送失败。所以我们在保证生产者发送消息的时候也要配合执行ISR的数量。

    ​ 但是我们 acks=all的时候一般要配合禁用unClean, unClean是如果ISR中没有任何的分区的时候会选择第一个从分区来作为主分区,那么unClean选举出来的主分区也可能是没有数据的。

你可能感兴趣的:(rabbitmq,rocketmq,kafka)