当前位置: 首页 > news >正文

第十三章 RabbitMQ之消息幂等性

目录

一、引言

二、消息幂等解决方案

2.1. 方案一

2.2. 方案二


一、引言

幂等是一个数学概念,用函数表达式来描述是这样的:f(x) = f(f(x)) 。在程序开发中,则是指同一个业务,执行一次或多次对业务状态的影响是一致的。有些业务天生就是幂等的,如查询和删除业务执行一次和多次的结果是一样的,而像用户下单、用户退款是非幂等业务。

实际项目开发中,我们在提交表单时,很多时候可能会重复提交表单,这个时候我们通过token令牌等唯一标识来解决,第一次提交页面将缓存中的唯一标识删除,后面再重新提交时缓存中的标识已经被删了因此重复提交失败。

我们在消息消费的过程中也会存在同样的问题,即如何来保障所有业务在接收RabbitMQ消息时保证业务的幂等性,避免消息重复消费呢?

二、消息幂等解决方案

2.1. 方案一

1. 给每个消息都设置/生成一个唯一id,利用id区分是否是重复消息,与消息一起投递给消费者。

2. 消费者接收到消息后处理自己的业务,业务处理成功后将消息ID保存到数据库

3. 如果下次又收到相同消息,去数据库查询判断是否存在,存在则为重复消息放弃处理

 核心代码:

我们可以在生产者和消费者两端分别声明消息转换器的Bean,本案例为了方便直接在启动类中声明消息转换器,并配置自动为消息创建id。

package com.example.consumer;import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;@SpringBootApplication
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class, args);}@Beanpublic MessageConverter messageConverter(){// 1.定义消息转换器Jackson2JsonMessageConverter jjmc = new Jackson2JsonMessageConverter();// 配置自动创建消息id,用于识别不同消息,也可以在业务中基于ID判断是否是重复消息jjmc.setCreateMessageIds(true);return jjmc;}
}
package com.example.publisher;import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;@SpringBootApplication
public class PublisherApplication {public static void main(String[] args) {SpringApplication.run(PublisherApplication.class, args);}@Beanpublic MessageConverter messageConverter(){// 1.定义消息转换器Jackson2JsonMessageConverter jjmc = new Jackson2JsonMessageConverter();// 配置自动创建消息id,用于识别不同消息,也可以在业务中基于ID判断是否是重复消息jjmc.setCreateMessageIds(true);return jjmc;}
}

通过源码可以看到默认生成的是UUID:

 通过RabbitMQ浏览器界面可以看到消息已经生成了一个唯一ID :

2.2. 方案二

结合业务逻辑,基于业务本身做判断。以余额支付业务为例,我们要在支付后修改订单状态为已支付,应该在修改订单状态前先查询订单状态,判断状态是否是未支付。只有未支付订单才需要修改,其他状态不做处理:

核心代码 

 上述代码可以通过乐观锁来实现,替换代码如下:

 

相关文章:

第十三章 RabbitMQ之消息幂等性

目录 一、引言 二、消息幂等解决方案 2.1. 方案一 2.2. 方案二 一、引言 幂等是一个数学概念,用函数表达式来描述是这样的:f(x) f(f(x)) 。在程序开发中,则是指同一个业务,执行一次或多次对业务状态的影响是一致的。有些业务…...

tpcms-master.zip

网盘:https://pan.notestore.cn/s.html?id34https://pan.notestore.cn/s.html?id34...

Spring国际化和Validation

SpringBoot国际化和Validation融合 场景 在应用交互时,可能需要根据客户端得语言来返回不同的语言数据。前端通过参数、请求头等往后端传入locale相关得参数,后端获取参数,根据不同得locale来获取不同得语言得文本信息返回给前端。 实现原…...

②EtherCAT转ModbusTCP, EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关

EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关https://item.taobao.com/item.htm?ftt&id822721028899 协议转换通信网关 EtherCAT 转 Modbus TCP (接上一章) GW系列型号 配置说明 上载 网线连接电脑到模块上的 WEB 网页设置网口&#…...

【华为HCIP实战课程八】OSPF网络类型及报文类型详解,网络工程师

一、点到点网络类型 1、两台路由器 2、支持广播、组播 P2P(PPP、HDLC、帧中继子接口) 我们需要三个维度考虑 A、是否自动通过组播发现邻居 B、时间(Hello和Dead) C、DR和BDR----多点接入网络需要用到(广播和NBMA) 点到点是组播自动发现邻居,Hello 10S,Dead 40S…...

信息安全工程师(28)机房安全分析与防护

前言 机房安全分析与防护是一个复杂而细致的过程,涉及到物理安全、环境控制、电力供应、数据安全、设备管理、人员管理以及紧急预案等多个方面。 一、机房安全分析 1. 物理安全威胁 非法入侵:未经授权的人员可能通过门窗、通风口等进入机房,…...

大数据处理从零开始————9.MapReduce编程实践之信息过滤之学生成绩统计demo

1.项目目标 1.1 需求概述 现在我们要统计某学校学生的成绩信息,筛选出成绩在60分及以上的学生。 1.2 业务分析 如果我们想实现该需求,可以通过编写一个MapReduce程序,来处理包含学生信息的文本文件,每行包含【学生的姓名&#x…...

自动化测试 | 窗口截图

driver.get_screenshot_as_file 是 Selenium WebDriver 的一个方法,它允许你将当前浏览器窗口(或标签页)的截图保存为文件。这个方法对于自动化测试中的截图验证非常有用,因为它可以帮助你捕获测试执行过程中的页面状态。 以下是…...

初中数学网上考试系统的设计与实现(论文+源码)_kaic

初中数学网上考试系统的设计与实现 学生: 指导教师: 摘 要:科技在人类的历史长流中愈洗愈精,不仅包括人们日常的生活起居,甚至还包括了考试的变化。之前的考试需要大量的时间和精力,组织者还需要挑选并考查…...

关系运算(3)

关系代数 昨天讲完附加关系代数运算,今天讲扩展关系代数运算。 扩展代数运算 正如其名,这种运算定义了前面基本和附加都没有的运算。 去重运算 可以将关系R中跟查询条件相关但是形成了重复的元组去除,只保留查询结果(简洁&…...

tp6的系统是如何上架的

TP6(ThinkPHP6)的系统上架过程,通常指的是将基于ThinkPHP6框架开发的应用程序部署到生产环境,并使其可以通过互联网访问。以下是一个大致的上架流程,包括准备工作、部署步骤以及后续维护等方面: 一、准备工…...

Vue:开发小技巧

目录 1. Table表格偏移 1. Table表格偏移 通过设置自小的宽度进行控制 :min-width <el-table-column label"操作" align"center" class-name"small-padding fixed-width" fixed"right" min-width"150px"><templa…...

力扣之1369.获取最近第二次的活动

题目&#xff1a; sql建表语句 Create table If Not Exists UserActivity (username varchar(30), activity varchar(30), startDate date, endDate date); Truncate table UserActivity; insert into UserActivity (username, activity, startDate, endDate) values (Alic…...

Python 和 Jupyter Kernel 版本不一致

使用jupyter notebook时明明已经安装了包&#xff0c;但是导入时提示&#xff1a; ModuleNotFoundError: No module named ptitprince 1、检查安装环境 !pip show ptitprince Name: ptitprince Version: 0.2.7 Summary: A Python implementation of Rainclouds, originally…...

Android常用布局

目录 布局文件中常见的属性 1. 基本布局属性 1&#xff09;android:layout_width 2&#xff09;android:layout_height 3&#xff09;android:layout_margin 4&#xff09;android:padding 2. 线性布局 (LinearLayout) 属性 1&#xff09;android:orientation 2&#xff09;and…...

初级网络工程师之从入门到入狱(五)

本文是我在学习过程中记录学习的点点滴滴&#xff0c;目的是为了学完之后巩固一下顺便也和大家分享一下&#xff0c;日后忘记了也可以方便快速的复习。 网络工程师从入门到入狱 前言一、链路聚合1.1、手动进行链路聚合1.1.1、 拓扑图&#xff1a;1.1.2、 LSW11.1.3、 LSW2 1.2、…...

JavaScript轮播图实现

这个代码创建了一个简单的轮播图&#xff0c;可以通过点击左右箭头或自动播放来切换图片。 <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>js轮播图练习</title><style>.box {width: 60vw;height: 500px;m…...

【LLM开源项目】LLMs-开发框架-Langchain-Tutorials-Basics-v2.0

【1】使用LCEL构建简单的LLM应用程序(Build a Simple LLM Application with LCEL) https://python.langchain.com/docs/tutorials/llm_chain/ 如何使用LangChain构建简单的LLM应用程序。功能&#xff1a;将把文本从英语翻译成另一种语言。 实现&#xff1a;LLM调用加上一些提…...

Python 爬取天气预报并进行可视化分析

今天&#xff0c;我们就来学习如何使用 Python 爬取天气预报数据&#xff0c;并用数据可视化的方式将未来几天的天气信息一目了然地展示出来。 在本文中&#xff0c;我们将分三步完成这一任务&#xff1a; 使用 Python 爬取天气数据数据解析与处理用可视化展示天气趋势 让我…...

最左侧冗余覆盖子串

题目描述 给定两个字符串 s1 和 s2 和正整数 k&#xff0c;其中 s1 长度为 n1&#xff0c;s2 长度为 n2。 在 s2 中选一个子串&#xff0c;若满足下面条件&#xff0c;则称 s2 以长度 k 冗余覆盖 s1 该子串长度为 n1 k 该子串中包含 s1 中全部字母 该子串每个字母出现次数…...

玩大型游戏用什么主板好:2026年市场格局与技术趋势解析

2026年第一季度&#xff0c;全球游戏级电脑主板市场正经历一场深刻的价值重塑。据行业研究机构数据显示&#xff0c;2026年全球游戏级主板市场规模预计将达到127.5亿美元&#xff0c;年复合增长率保持在8.30%的稳健水平。在这一轮增长周期中&#xff0c;单纯依靠硬件堆砌的时代…...

Janus-Pro-7B 软件设计模式解析:结合实例讲解23种经典模式

Janus-Pro-7B 软件设计模式解析&#xff1a;结合实例讲解23种经典模式 1. 为什么设计模式值得你花时间 每次看到别人写的代码清晰又灵活&#xff0c;自己写的却像一团乱麻&#xff0c;是不是有点头疼&#xff1f;或者接手一个老项目&#xff0c;光是理清各个模块怎么调用的就…...

OpenClaw技能扩展指南:为nanobot添加自定义QQ机器人功能

OpenClaw技能扩展指南&#xff1a;为nanobot添加自定义QQ机器人功能 1. 为什么需要QQ机器人集成 去年夏天&#xff0c;我发现自己经常在深夜调试代码时&#xff0c;需要反复切换手机和电脑查看运行结果。这种低效的操作让我开始寻找一种更优雅的解决方案——通过聊天工具直接…...

无需高配电脑!VMware虚拟机运行Qwen3-TTS声音克隆实测教程

无需高配电脑&#xff01;VMware虚拟机运行Qwen3-TTS声音克隆实测教程 1. 为什么选择虚拟机部署声音克隆&#xff1f; 很多开发者对语音克隆技术感兴趣&#xff0c;但往往被硬件要求劝退。传统认知中&#xff0c;运行1.7B参数量的AI模型需要高端显卡和复杂的环境配置。实际上…...

ArcGIS模型构建器实战:一键加载上百个SHP文件(含子文件夹)的保姆级教程

ArcGIS模型构建器实战&#xff1a;一键加载上百个SHP文件&#xff08;含子文件夹&#xff09;的保姆级教程 当你在城市规划部门接手一个历史遗留项目&#xff0c;或是从不同合作方收到几十个分散的SHP文件时&#xff0c;是否经历过这样的崩溃瞬间&#xff1f;每个文件夹挨个点开…...

从One-Hot到Embedding:一文读懂NLP中的词向量进化史

从One-Hot到Embedding&#xff1a;一文读懂NLP中的词向量进化史 在自然语言处理&#xff08;NLP&#xff09;的发展历程中&#xff0c;如何有效地表示单词一直是核心挑战之一。早期的计算机科学家们发现&#xff0c;要让机器理解人类语言&#xff0c;首先需要解决"词如何数…...

MangoHud源码静态分析报告:潜在问题列表

MangoHud源码静态分析报告&#xff1a;潜在问题列表 【免费下载链接】MangoHud A Vulkan and OpenGL overlay for monitoring FPS, temperatures, CPU/GPU load and more. Discord: https://discordapp.com/invite/Gj5YmBb 项目地址: https://gitcode.com/gh_mirrors/ma/Mang…...

OpenClaw语音交互方案:GLM-4.7-Flash对接ASR/TTS

OpenClaw语音交互方案&#xff1a;GLM-4.7-Flash对接ASR/TTS 1. 为什么需要语音交互的OpenClaw&#xff1f; 上周三凌晨两点&#xff0c;我正在赶一份项目报告时突然冒出一个想法&#xff1a;如果能用语音控制OpenClaw执行自动化任务&#xff0c;是不是能彻底解放双手&#x…...

百川2-13B驱动OpenClaw智能客服:电商售后场景的自动化响应实战

百川2-13B驱动OpenClaw智能客服&#xff1a;电商售后场景的自动化响应实战 1. 为什么选择OpenClaw搭建轻量级客服系统 去年双十一期间&#xff0c;我运营的小型电商店铺遭遇了售后咨询暴增的问题。临时雇佣的客服人员不熟悉产品细节&#xff0c;导致大量重复问题需要反复解答…...

Cherry Studio集成火山方舟模型实战:从接入到性能调优全解析

最近在项目中尝试将火山方舟的模型集成到 Cherry Studio 里&#xff0c;整个过程踩了不少坑&#xff0c;也总结了一些经验。今天就来和大家分享一下从接入到性能调优的完整实战过程&#xff0c;希望能帮到有同样需求的开发者。 1. 背景与痛点&#xff1a;为什么集成过程让人头疼…...