RabbitMQ如何保证消息不被重复消费(幂等性问题详解)

举报
辰兮 发表于 2022/03/22 23:30:03 2022/03/22
【摘要】 【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行! 博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后台、...

【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行!

博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后台、数据库、项目案例等相关知识点总结,感谢你的阅读和关注,希望我的博客能帮助到更多的人,分享获取新知,大家一起进步!

吾等采石之人,应怀大教堂之心,愿我们奔赴在各自的热爱里…


一、幂等性概念简介

幂等:是一个数学概念,表示N次变换和1次变换的结果相同。

在这里插入图片描述

在计算机中编程中,一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。


二、接口幂等性问题原因

  • 网络波动, 可能会引起重复请求
  • 页面重复刷新
  • 浏览器重复的HTTP请求
  • 定时任务重复执行
  • 用户双击提交按钮
  • 数据的重复推送等等

如上等等,很多业务场景都会导致幂等性问题!

举个例子:比如你购物只想购买一件商品,但是网络卡顿,你按了多次提交按钮后,系统将此订单生成了两次!如上即数据库生成了两条订单记录!即产生了幂等性的问题!

正确的情况: 一个商品页点提交,只会产生一条订单信息!


三、业务场景实例+解决方案

业务场景:数据中心通过消息队列往我们嫌疑人资源表中推送数据(RabbitMQ消费者开始消费)

推送流程:手动和自动(按时间推);

手动推送:手动过程可以自选如推送2022年1月数据数据或者推送 2022年1月和二月数据

在这里插入图片描述


嫌疑人资源表结构举例

在这里插入图片描述

导致问题:如果不做幂等性处理,数据库该表中会出现重复的嫌疑人案件信息


解决方案

A. 设计全局唯一消息id

1.推送过来的数据我们在业务逻辑层处理 主键id设计为 案件id+嫌疑人id,插入到数据库
2.后续推送的数据,我们先根据主键id 查询数据库中是否存在,如果存在则过滤掉此数据,如果不存在则插入数据库

B.数据库唯一主键

1.数据库DB层面,主键也是不能冲突的,重复的数据是无法插入的

如上即解决了本业务场景中嫌疑人相关案件信息重复推送的问题


业务场景提问

为什么不直接使用嫌疑人id当中主键呢?

请添加图片描述

:因为一个人可能会犯多次案件,当嫌疑人id+案件id拼接在一起的时候即可保障此数据的唯一性!


四、思路分享

解决数据消息不重复消费问题从 Service层和DB两个层面考虑问题,设计一个全局id,同时数据库设计唯一主键

请添加图片描述

其余不同业务场景

1、部分场景下数据重复推送可能部分细节会发生变化,先根据主键查一下,如果这数据都有了,就进行update 操作

2、如果你不能将唯一主键存储在id位置,可以设置唯一索引

如上案例:将案件id+嫌疑人id设计为唯一索引


引入Redis解决重复消费问题

请添加图片描述

1、利用Redis,首先系统生成全局唯一的 id,用set操作放入Redis中
2、如订单信息id,消费后存储在Redis中,如果下次再来,先查看Redis中是否存在
3、如果存在,即此消息已经被消费过(后续不做消费处理)
4、如果不存在,即未消费,此时再将此id存入Redis中,进行后续的逻辑操作

在这里插入图片描述

Java进阶参考Java面试总结整理

期待整理更多有趣的文章,我下期再见……


非常感谢你阅读到这里,如果这篇文章对你有帮助,希望能留下你的点赞👍 关注❤️ 分享👥 留言💬thanks!!!

📚愿我们奔赴在各自的热爱里!

文章来源: blessing.blog.csdn.net,作者:辰兮要努力,版权归原作者所有,如需转载,请联系作者。

原文链接:blessing.blog.csdn.net/article/details/123150714

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。