RocketMQ实战-生产者发送顺序消息的关注点

434 阅读3分钟

基于V4.9.4版本的RocketMQ源码解析专栏

RocketMQ实战专栏

本期重点内容

本期主要聊一下RocketMQ顺序消息方面的内容,主要关注点在于消息生产者发送顺序消息应该关注的几个重要事项,避免用户在发送顺序消息时,明明是按照客户端API使用的,但是发现消息并不是有序的。

生产消息顺序性关键点

单一生产者

生产消息的顺序性只支持单一的生产者,不同的生产者发送的消息很难保障顺序性,因为其分布在不同的系统中或者分布在集群中的不同节点上面,即使设置相同的分区键,也无法保障其发送的先后顺序。

串行发送

使用单一生产者进行串行发送,能够保障消息的顺序性,但若多线程并发的发送消息,就无法保障消息的顺序性了。

分区键

相同分区键的消息,经过同样的路由队列策略后,会选取队列集合中相同的队列。

可用性保障

发送顺序消息是需要面临可用性与严格顺序性两个方面抉择的,选择了可用性就无法保障严格的顺序性,选择了严格的顺序性就无法保障消息队列的可用性。

重点内容解析

本篇的重点内容解析主要涉及顺序消息的可用性与严格顺序性两个方面

顺序消息可用性

image.png

消息生产者通过ShardingKey来选择要发送的队列,图示的几条消息其ShardingKey是一致的,待选取的Topic队列为四个,分布在两个Broker上面,经过Sharding算法,选取的会是同一个队列。

image.png

若此时BrokerB掉线,那么Topic对应的队列个数就会变更为两个,此时经过Sharding算法,选取的队列会发生变换,就会导致消息乱序的产生。

以上的内容就是保障了顺序消息的可用性,当其中一个Broker掉线后,本地缓存的Topic队列发生变更,剔除掉线Broker关联的队列,其余的队列仍然能够发送消息成功,保证了消息发送的可用性,只不过,会导致消息乱序的出现。

严格顺序性

要保障消息发送严格的顺序性,就要牺牲可用性,也就是当其中的一个broker掉线时,消息队列的个数不变,经过Sharding算法选取的仍然是同一个队列,只不过消息发送会失败。

严格消息的顺序性是在创建Topic时指定的,指定参数为 -o 参数(--order)为true,并且NamerServer的orderMessageEnable配置为true,这种情况下就保障了消息严格的顺序性。

我们来看一下严格消息顺序性是怎么实现的

就是在创建Topic的命令中,将顺序队列的个数固定化了,不受任何broker宕机的影响。

image.png

另一方面,在同步Topic队列信息的时候,解析的就是创建Topic的时候固定拼接队列字符串。 image.png

以上两点实现,保障了消息严格的顺序性,只不过当其中一个节点宕机的时候,部分消息队列不可用,这是需要关注并解决的点。