消息队列并发消费时保证部分消息的顺序性

本文以go语言和nats消息队列为例,探讨多实例部署且每个实例都是多线程消费消息时如何确保部分消息的有序性。

应用场景

队列中会存在对同一条数据(如id一样)的增删改查,如果直接使用多线程消费会存在顺序错乱的可能,或者并发消费的可能性,导致最终状态不一致。

方案探讨

1.使用分布式锁

如果对同一条id的数据进行加redis分布式锁,确实可以保证消息不会并发消费,但是无法保证顺序,如123可能会变为132。

2.发消息时带时间戳

比对此次消费时间戳和上次时间戳,大了就消费,小了就丢弃。这种方法可以先来的后消费,但是会存在丢消息的情况如123变为13,将2丢弃。这种方案如果后一次是全量的操作则不会影响,但是依然不够优雅。

解决方案

1.解决多节点的并发消费问题

要多节点不会并发消费同一个id的消息,核心思路是将同一个id的消息全部发往同一个节点,这里以nats举例,将在topic中包含id字段,nats通过设置可以对topic进行hash运算,从而确定发往哪一个节点,这样同一个id必然会发往同一个节点。

2.解决单节点多线程的并发消费问题

我们的思路依然是通过hash计算,将同一个id固定使用同一个线程消费,这样就不会存在并发问题,在go语言中可以使用20个协程,并发消费20个管道,每个协程只消费自己对应的管道,在接受到消息时根据id字段hash取模后放入对应的管道中即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值