面试题答案
一键面试RocketMQ保证消息顺序性的方式
- 生产者:生产者在发送消息时,可以通过设置消息的
MessageQueueSelector
来指定消息发送到特定的队列。如果所有相关消息都发送到同一个队列,那么在该队列上消息是有序的。例如,在处理交易记录时,按照交易ID的某种规则(如哈希取模)将同一交易相关的消息都发送到同一个队列。 - 消费者:消费者从队列拉取消息时,采用单线程消费模式。RocketMQ的
MessageListenerOrderly
监听器会确保在一个队列上,消息按顺序依次被消费。也就是说,消费者在处理某个队列的消息时,只有前一条消息处理完成,才会处理下一条消息。
可能出现乱序的原因
- 多队列消费:如果生产者没有正确设置
MessageQueueSelector
,导致同一业务逻辑相关的消息被发送到了不同队列。而消费者对多个队列是并行消费的,就可能出现乱序。例如,不同交易的消息分散在多个队列,消费者并行处理不同队列消息时,交易记录顺序就可能错乱。 - 消费端异常:当消费者在消费过程中出现异常(如程序崩溃、长时间阻塞等),重启后可能从队列的当前位置继续消费,而之前未处理完成的消息可能会在后续处理,导致局部乱序。
- 网络抖动:在消息传输过程中,由于网络抖动等原因,可能导致消息在队列中的存储顺序和实际到达消费者的顺序略有差异,不过这种情况相对较少。