前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >RabbitMQ如何保证消息幂等?

RabbitMQ如何保证消息幂等?

作者头像
用户10136162
发布2023-10-30 14:44:42
1670
发布2023-10-30 14:44:42
举报
文章被收录于专栏:Eliauk的小窝Eliauk的小窝

RabbitMQ如何保证消息幂等?

1、生产端做消息幂等 (即不重复投递)

在生产端的话,其实消费端做好幂等,生产端就算投递多次,也无所谓了。 如果实在想在生产者做幂等的话,可以参考消费端的思路,比如通过redis的 setnx (key可以设计成 producer:具体业务:具有唯一性的某几个或者某一个业务字段 作为key) ,添加防重表等等。但是我个人觉得没必要。把消费端做好幂等就可以了。

2、消费端做消息幂等 (即不重复消费)

A、方案

代码语言:javascript
复制
 /** 
  * 是否能消费,用于防止重复消费
  * false 代表未消费过 ,true代表消费过
  * 
  * @param  content 
  * @param  queueName 
  * @return  
 */
private Boolean checkConsumedFlag(T content, String queueName) {
    String messageKey = queueName + ":" + content.getId();
    if (StringUtils.isBlank(redisTemplate.opsForValue().get(messageKey))) {
        //从redis中没获取到value,说明未消费过该消息,返回true
        return false;
    } else {
        //获取到了value说明消费过,然后将该消息标记为已消费并直接响应ack,不进行下边的业务处理,防止消费n次(保证幂等)
        redisTemplate.opsForValue().set(messageKey, "lock", 60, TimeUnit.SECONDS);
        //事实上,set操作应该放在业务执行完后,确保真正消费成功后执行。这里偷个懒。写在业务执行前了。
        return true;
    }
}

B、方案(防重表)

并发高情况下可能会有IO瓶颈 (先读在写) 该方式需要在发送消息时候,指定一个业务上唯一的字段。 如 xzll:order:10001 (10001代表订单id) 然后,在消费端获取该字段,并插入到防重表中(插入代码写在哪?) 如果你声明了事务,那么插入防重这段代码位置无需关注(因为出现异常肯定会回滚), 如果没实现事务,那么最好在执行完业务逻辑后,再插入防重表,保证防重表中的数据肯定是消费成功的。实现步骤: 接收到消息后,select count(0) from 防重表 where biz_unique_id=message.getBizUniqueId(); 如果大于0,那么说明以及消费过,将直接ack,告知mq删除该消息。如果=0说明没消费过。进行正常的业务逻辑。

C、方案(唯一键 : 真正保证了幂等)

直接写) 如果消费端业务是新增操作,我们可以为某几个或者某一个字段设置业务上的唯一键约束, 如果重复消费将会插入两条相同的记录,数据库会报错从而可以保证数据不会插入两条。

D、方案(乐观锁)

并发高下也可能会产生IO瓶颈 (先读再写) 如果消费端业务是更新操作(例如扣减库存), 可以给业务表加一个 version 字段,每次更新把 version 作为条件,更新之后 version + 1。 由于 MySQL的innoDB是行锁,当其中一个请求成功更新之后,另一个请求才能进来(注意此时该请求拿到的version还是1), 由于版本号version已经变成 2,所以更新操作不会执行,从而保证幂等。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-10-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • RabbitMQ如何保证消息幂等?
    • 1、生产端做消息幂等 (即不重复投递)
      • 2、消费端做消息幂等 (即不重复消费)
        • A、方案
        • B、方案(防重表)
        • C、方案(唯一键 : 真正保证了幂等)
        • D、方案(乐观锁)
    相关产品与服务
    数据库
    云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档