消息队列中的消息是并行执行的,消息之间有顺序依赖怎么办?

ajianrelease
  • 199

之前发的贴子没说明白,重新发吧。此例只用于说明异步消息并行执行时会出现的问题。

这里用评论微博来举例好了。
A评论B后,会给B发异步通知,然后A删除评论时,会异步删除这个通知。

问题:消息队列中有两个消息:发通知和删除通知,由于有并发(多个消费者),可能先执行的是删除通知,然后再执行发通知

回复
阅读 9.2k
4 个回答
ajianrelease
  • 199
✓ 已被采纳

目前有两种方案:
方案一:当删除评论时,检查一下评论对应的消息是否存在,如果不存在,那retry(Python celery支持)一次

方案二:大部分情况下,只有同一用户的异步消息会产生顺序依赖,所以按用户id做hash,保证同一用户进入同一队列,并且每个队列只有一个消费者。不过,由于每个队列只有一个消费者,随着用户量的增加,就要在broker中创建越来越多的队列,当然,我们可以使用多个broker

已注销
  • 36

假如是Kafka的多partition/RocketMQ的多message queue,如果要求强顺序性的,其中一个方案:可以考虑将发送的消息带上时间戳,在消费端把消息添加到一个分布式的redis有序集合,根据这个时间戳来排序取出来,就可以做到消息有序性;另一个方案是将消息放入一个partition/message queue,因为单个partition/message queue是消息有序性的

WoodenSail
  • 1.3k

你说的情况实际上可能发生在IM或BBS这样的高实时性系统中。这类系统由于其特性不可能每次都请求全部数据,而是只发送更新数据,这种情况下,只要在发包的时候加个时间戳就行了。对于一条message,前端需要将与它相关的信息按时间戳排序,以确定这条消息到最后到底是处于什么状态。

另外,如果是微博的例子的话那么只要做好服务器端事务的原子性就行了。
首先你的表述不是十分恰当,A和B都是在和服务器通信。一般情况下,在用户A的角度事情应该是这样的:数据库初始状态1,无评论;添加评论后到状态2,1条评论,删除后到状态3,无评论。
在用户B的角度,他做的就是向服务器发起一个请求查看当前评论,无论是在状态12或3,都不会有问题。
事实上,当A添加和删除评论时,一般情况下服务器不会直接通知B添加或删除了评论,而是等用户B重新请求。


原答案:
回调函数呗。
点赞后前端发起请求,页面无变化。服务器处理完返回后执行回调将页面变为已点赞状态。此时再单击才会触发取消点赞的事件。取消同样在等到回调之后才将页面变为未点赞状态。

注意:如果用户手快,连续点击就会发出同样的请求,可以考虑服务器端忽略重复请求或者,或者在前端用单次绑定等方法使得点完一次赞后后续点击无效。

pfeng
  • 207

个人认为,你在ajaxstart的时候把按钮禁用,ajaxstop时再把按钮解禁,是一个比较容易实现的低成本方案。

 $(document)
            .ajaxStart(function(){
                $("button:submit").attr("disabled", true);
            })
            .ajaxStop(function(){
                $("button:submit").attr("disabled", false);
            });
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏