一、幂等性概念简介

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

springboot rabbitmq 消息不被重复消费_分布式

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


二、接口幂等性问题原因

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

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

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

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


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

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

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

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

springboot rabbitmq 消息不被重复消费_经验分享_02


嫌疑人资源表结构举例

springboot rabbitmq 消息不被重复消费_经验分享_03

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


解决方案

A. 设计全局唯一消息id

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

B.数据库唯一主键

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

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


业务场景提问

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

springboot rabbitmq 消息不被重复消费_经验分享_04

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


四、思路分享

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

springboot rabbitmq 消息不被重复消费_java_05

其余不同业务场景

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

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

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


引入Redis解决重复消费问题

springboot rabbitmq 消息不被重复消费_面试_06

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

springboot rabbitmq 消息不被重复消费_经验分享_07