如何保证消息的顺序性的?
如何保证消息的顺序性的?
提示
题眼: TCP 的重传机制
消息的顺序性,一直是比较难解决的问题,如果可以,在需要业务顺序的场景下,不使用消息队列可能是最好的选择。
一般情况下,消息顺序性是说一个业务行为的顺序,比如说最常见的电商系统里,用户浏览,加购,下单,付款,发货这一个流程,一般保证消息是先加购,再结算,再下单,再付款整个过程的顺序。不同用户的下单支付,不必考虑,因为用户 id 的隔离,彼此之间不会出现 用户 A 替用户 B 支付的情况。这一点格外注意,千万不要画蛇添足。
重要
参考答案:
因为 kafka 的分区设计,topic 的数据会分在多个分区上,想要实现消息的顺序性,其实还是很麻烦的。如果是非常强的要求,可以设置成一个生产者,发送到指定分区里,然后一个消费者专门读取。这样的好处是,绝对有序,缺点是牺牲了消息队列的优势,效率不太高。
如果是想要实现一定程度上的有序,可以优化一下。
首先,生产端这边,需要保证消息有序。一般情况下,咱们的服务都是多生产者,可以用业务 ID 做版本号,把一个消息分成 1234 这种,并且要在消息体中写清楚,一共有几个消息,这是第几号消息。
然后存储这边就正常使用,消费端需要做一些业务上的调整,一般为了保证有序,都只会安排一个消费端,当收到这种消息后,可以先存储到本地缓存里,然后等所有数据到齐后再一起处理,这样就实现接收是同步的,然后处理事串行的,这样子可以保证效率,并且有序。
但是,这种也存在问题,就是如果中间消息丢失了或者积压了,问题比较难处理。一般情况下,都是设置一个最大等待时间,如果过期了还没有收全消息,就写日志,然后丢弃,不能影响后续服务。
(切记,一般不推荐使用消息队列的同时,又要保证消息顺序)
相关信息
引申: 其他消息队列如何保证顺序性的。
