首页 新闻 搜索 专区 学院

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

0
悬赏园豆:10 [已解决问题] 解决于 2015-01-23 09:47

这里用评论微博来举例好了。

A评论B后,会给B发异步通知,然后A删除评论时,会异步删除这个通知。

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

奋斗终生的主页 奋斗终生 | 初学一级 | 园豆:30
提问于:2015-01-21 11:51
< >
分享
最佳答案
0

给入队消息和表都加个时间字段,更新数据库时只更新消息时间大于表中时间的记录。

收获园豆:7
Launcher | 高人七级 |园豆:45045 | 2015-01-21 12:39

我举的例子中一个是删除,一个是创建,没有更新啊?

奋斗终生 | 园豆:30 (初学一级) | 2015-01-21 15:00

@平和的心: 虽然你把原来的描述都删除了,又新写了一堆,不过没关系,还是可以照着你这种错误的设计做的,软件工程中有句很著名的话是这样说的:所有的软件设计的问题都可以通过增加一个抽象的间接层而得到解决或者得到简化。

我们只要把握一个关键点:依据入队时间(或出队时间,甚至更简洁的使用递增的计数值)来决定哪些消息是要被丢弃的。因为你这里只有创建和删除,那么为了保证“留痕”,我们可以提供一个额外的单独的表来实现,此表结构很简单,记录被操作的记录的主键和一个数值(入队时间、出队时间或递增计数值),每次执行创建、删除前先更新此值,更新的原则还是更我之前讲的一样,只有大于此数值的可以更新成功,更新成功后再执行你的在数据表中创建或删除的操作。

Launcher | 园豆:45045 (高人七级) | 2015-01-21 16:59

@Launcher: 哎,看不懂。我现在的方案就是删除前检查一下通知是否存在,如果不存在,间隔一定时间,重新生成一条与原来一样的消息放入消息队列。另外,还会设定最多重试次数。

奋斗终生 | 园豆:30 (初学一级) | 2015-01-22 15:00
其他回答(2)
0

为什么不是个完整的事务? 为什么不是点赞+1后发通知,返回前端。   

收获园豆:3
问天何必 | 园豆:3301 (老鸟四级) | 2015-01-21 12:29

亲,这个不是重点,这只是一个例子而已,重点是:怎么处理异步消息在被并行处理时的乱序问题

支持(0) 反对(0) 奋斗终生 | 园豆:30 (初学一级) | 2015-01-21 12:59

@平和的心:  

异步异步不是同步,并行时肯定有乱序问题, 就算你自己diy所有消息队列处理程序,让它们排队等待,这也算是脱了裤子放屁。 

所以,你加个时间戳来区别记录, 就像楼下说的一样, 这样最简单。 

像这种异步并行, 在设计流程上就应该规避。 

支持(0) 反对(0) 问天何必 | 园豆:3301 (老鸟四级) | 2015-01-21 14:36

@问天何必: 没明白,给异步消息加个时间戳?用时间戳怎么解决上面说的问题呢?还能再细说一下吗?

支持(0) 反对(0) 奋斗终生 | 园豆:30 (初学一级) | 2015-01-21 14:39

@平和的心: 没办法做, 想法是错误的。 不好意思, 我再想想。 

支持(0) 反对(0) 问天何必 | 园豆:3301 (老鸟四级) | 2015-01-21 16:24

@问天何必:  想了很久, 

你这种设计真是太扯蛋了,就算你只是举了个栗子。但是设计本质依旧是扯蛋。。。

你的问题应该被简化: 连通知的数据都没有建立好,发个毛的发、 删个毛的删。 评论和通知的数据建立不能用同步方式么?

可以删通知的前提是你已经有这条通知的数据了。 

反过来想, 你可以去看看观察者模式这种设计模式, 用回调函数  来标识你的通知数据已经建立好了,可以发送了、可以删除了也同理。

 

支持(0) 反对(0) 问天何必 | 园豆:3301 (老鸟四级) | 2015-01-21 17:06

@问天何必:  又想了一下, 发送和删除操作的发起者都是同一个客户端?

看你举的两个栗子,其实根本不需要动数据库,js方法就OK, 你可以创建一个数组存储ajax请求队列,数组中每一项又是一个请求参数数组, 每次有新请求都是push到末尾,当用户执行操作请求时, 不是直接执行ajax,而是将参数们作为对象存入队列中,按顺序执行,执行完成后就清除队列,不就好了吗? 

你可以看看ajax队列的文章,如果用的是jquery那更好,可以看queue()、dequeue()、clearqueue()方法,  

看了楼下高人的回答, 建一个记录表的方式也不错。如果发起者不是同一个的话, 你就用他的方式。

说到底你就是得控制它们按顺序执行。 

支持(0) 反对(0) 问天何必 | 园豆:3301 (老鸟四级) | 2015-01-21 18:10

@问天何必: 谢谢。发送和删除有可能不是一个客户端

支持(0) 反对(0) 奋斗终生 | 园豆:30 (初学一级) | 2015-01-22 15:01
0

按你的描叙,只能说是执行取消点赞的之前就去检查是否有未处理的点赞通知,有的话先删了再执行取消点赞。

前提是取消点赞操作必须迟于点赞通知的生成。

arg | 园豆:1047 (小虾三级) | 2015-01-21 14:32
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册