2
回答
求解消息队列的消息乱序处理问题
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   

问题场景描述:

消息发送方发送三条消息M1、M2、M3到消息Broker。消息接收方从消息Broker接收消息。如果发送方发送消息过快,那么在消息接收方得到的消息可能依次是M1、M3、M2,或者M1、M3、M2等。

而如果消息处理顺序不一样,得到的结果也是不一样的。比如M1是更新姓名为jxq,M2是更新姓名为will,M3是更新姓名为love,那么消息处理顺序不同得到的结果可能是jxq、will和love三种情况。

我的思考:

以前涉猎过分布式系统中的Lamport逻辑时钟(http://blog.nosqlfan.com/html/4227.html http://www.cyanny.com/2013/11/24/distributed-system-review-part2/),但没有实质理解,所以没法迁移应用到这个上面来。

然后想到一种不太理想的方案:

给消息进行唯一编号,编号越大的应该越后被处理。然后在内存中维护一个优先级队列,从RabbitMQ消息队列中收到消息后先进入内存中的优先级队列,每个消息必须等待五分钟(具体时间可以配置)才能被处理,比如现在M1、M3先收到,进入优先级队列,然后过了3分钟来了M2,优先级队列中的消息顺序变成M1、M2、M3。这样一定程度上保证了消息处理的时序性。并且每次处理完成都会记录当前处理的消息的最大编号。

当然如果M2超过5分钟才收到,发现当前已处理的最大消息编号是M3的编号,它大于M2的编号,那么这种情况可以直接丢弃消息,或者将消息提交给客服进行人工审核。

求问大家有没有什么建议?

<无标签>
举报
优雅先生
发帖于3年前 2回/775阅

请教实现方案

--- 共有 2 条评论 ---
优雅先生更新数据记录的更新时间,则说明该消息已过期,直接丢弃消息即可。如果消息中的业务发生时间晚于待更新记录的更新时间,则根据id去原始数据源读取最新数据状态并更新到待同步数据表中即可。 11个月前 回复
优雅先生这种有一种简单但有限制的方法。首先要求Producer端发送消息是顺序的,然后在Consumer端限制消费者线程数为1,这样就能保证顺序消费消息了。 但另外一种更靠谱的做法是保证消息处理幂等性,这样就不用管消息顺序了,提示一点:要保证消息幂等性,不要在消息中包含太多信息,一般消息中只包含id和业务发生时间即可,消息处理时根据id去待同步更新的数据表中获取对应记录,如果消息中的业务发生时间早于待 11个月前 回复
顶部