顺序消息的解决思路

场景

在日常开发中各个系统之间的交互,除了系统调用之外消息也是一个比较常见的机制。比如:商品发布、商品上架、商品下架等,这种场景下为了与其他系统解耦所以选择使用消息中间件来进行消息的发布与订阅机制。除了这种场景之外,我们经常遇到另一个场景,比如有A和B两个系统,A系统负责商品的生命周期管理,比如发布、审核、上架、下架。B系统负责对商品的价格进行计算与价格审核相关的功能。我们知道商品在上架前肯定得有价格,而价格肯定是需要商家先提报然后需要审核之后B系统再对商家提报的价格进行一定的溢价计算才能生成最终在平台上的销售价格。那么商品提报之后不能说要等商家把价格信息完善好之后再继续往下进行商品运营工作,所以商品提报之后流程继续走,等到商家提报价格以及B系统生成价格之后,通过消息监听的机制来感知价格的变化情况。

分析

在前面我们提到,需要依赖商家提报价格以及B系统生成价格,而这些事件都是通过消息的机制来感知的。A系统的商品的价格状态是有两个,一个是商家提报的供货价,一个是商品的销售价。可以想到这里A系统的设计就天然的依赖了消息的顺序,A系统的价格状态的推进是现有供货价,然后再有销售价,这符合业务的逻辑。但是,仔细想想,这里就有一些分布式的问题。首先,价格的计算时间肯定很短,这两条消息若是同时发出,那这两条消息不一定能被同一个消费者消费。那么肯定会有“供货价没有提报,但是销售价已经生成”的情况(因为供货价提报的消息被另一台机器消费了,而且这个时候还没有写入数据库)。其二,即使两条消息能被同一个机器消费到,但我们其实知道MQ的消息可能会乱序(因为网络问题导致消费者没消费到,MQ会触发重发机制,但是这个时候消息就已经乱序了)

解决

数据冗余加补偿

将价格相关的数据冗余在自己系统里面,当B系统发出消息的时候我们将消息存数据库,然后我们再通过定时任务去补偿数据

消息重发

在系统判定还没有收到供货价的时候将消息转为延迟消息再次发送。不太推荐这样做,这样会影响到原来topic里面的数据,后续排查非常困难