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

JAVA:利用 RabbitMQ 死信队列实现支付超时场景的技术指南

1、简述

在支付系统中,订单支付的超时自动撤销是一个非常常见的业务场景。通常用户未在规定时间内完成支付,系统会自动取消订单,释放相应的资源。本文将通过利用 RabbitMQ 的 死信队列(Dead Letter Queue, DLQ)来实现支付超时自动撤销功能,并详细讲解如何在 Java 中进行实现。

在这里插入图片描述

2、什么是死信队列?

死信队列是 RabbitMQ 中的一个重要功能,当消息在某个队列中变成“死信”时,可以被发送到另一个特殊的队列,这个队列就是死信队列。消息变成死信的情况有三种:

  • 消息被拒绝(basic.reject 或 basic.nack),并且 requeue=false。
  • 消息的 TTL(Time to Live)过期。
  • 队列达到最大长度,无法再存入新消息。

通过死信队列,我们可以处理一些特殊的业务逻辑,例如订单支付超时自动撤销。

3、实现过程

我们将为每个新创建的支付订单设置一个超时时间(例如 30 分钟),在订单支付的过程中将订单的消息发送到 RabbitMQ。消息在 RabbitMQ 中设置一定的 TTL(生存时间)。如果用户在超时时间内完成支付,消息会被正常处理;如果超时未支付,消息会成为“死信”,被转移到死信队列,从而触发订单撤销的逻辑。

3.1 环境准备

首先,在 pom.xml 中添加 RabbitMQ 相关依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
3.2 RabbitMQ 配置

在 application.yml 中添加 RabbitMQ 的连接配置:

spring:rabbitmq:host: localhostport: 5672username: guestpassword: guest
3.3 配置普通队列和死信队列

我们需要配置两个队列,一个是正常的支付订单队列,另一个是死信队列。

  • 支付订单队列:用于接收支付订单的消息。
  • 死信队列:接收从支付订单队列中转移过来的超时未处理的消息。
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class RabbitMQConfig {// 正常交换机@Beanpublic DirectExchange orderExchange() {return new DirectExchange("order-exchange");}// 死信交换机@Beanpublic DirectExchange deadLetterExchange() {return new DirectExchange("dead-letter-exchange");}// 正常队列@Beanpublic Queue orderQueue() {return QueueBuilder.durable("order-queue").withArgument("x-dead-letter-exchange", "dead-letter-exchange") // 绑定死信交换机.withArgument("x-dead-letter-routing-key", "dead-letter-routing-key") // 死信路由键.withArgument("x-message-ttl", 1800000) // 消息的TTL(30分钟).build();}// 死信队列@Beanpublic Queue deadLetterQueue() {return QueueBuilder.durable("dead-letter-queue").build();}// 绑定正常队列和交换机@Beanpublic Binding orderBinding(Queue orderQueue, DirectExchange orderExchange) {return BindingBuilder.bind(orderQueue).to(orderExchange).with("order-routing-key");}// 绑定死信队列和死信交换机@Beanpublic Binding deadLetterBinding(Queue deadLetterQueue, DirectExchange deadLetterExchange) {return BindingBuilder.bind(deadLetterQueue).to(deadLetterExchange).with("dead-letter-routing-key");}
}
3.4 发送订单支付消息

在订单创建时,我们将消息发送到 RabbitMQ,设置 TTL(超时时间):

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class OrderService {@Autowiredprivate RabbitTemplate rabbitTemplate;public void createOrder(String orderId) {// 模拟创建订单的逻辑System.out.println("订单创建成功,订单ID:" + orderId);// 发送订单消息到RabbitMQrabbitTemplate.convertAndSend("order-exchange", "order-routing-key", orderId);System.out.println("订单消息已发送,等待支付超时或支付完成处理...");}
}
3.5 监听死信队列,实现超时自动撤销订单

当订单超时未支付,消息将转移到死信队列,我们通过监听死信队列,实现订单撤销逻辑:

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class DeadLetterQueueListener {@RabbitListener(queues = "dead-letter-queue")public void handleExpiredOrder(String orderId) {// 处理超时订单撤销的逻辑System.out.println("订单支付超时,自动撤销订单,订单ID:" + orderId);// TODO: 更新数据库订单状态为已取消}
}

4、总结

通过使用 RabbitMQ 的死信队列,我们可以轻松实现支付超时自动撤销的功能。具体流程如下:

  • 创建订单时,将订单消息发送到 RabbitMQ,并为消息设置 TTL。
  • 如果用户在规定时间内完成支付,系统处理消息,订单正常完成。
  • 如果消息在 TTL 时间内未被处理,消息进入死信队列,触发自动撤销逻辑。

利用 RabbitMQ 死信队列可以确保超时订单得到及时处理,避免资源浪费,同时还能保证系统的高并发处理能力。

这套方案可以扩展应用于任何有类似超时要求的业务场景,如购物车超时、订单确认超时等。

相关文章:

JAVA:利用 RabbitMQ 死信队列实现支付超时场景的技术指南

1、简述 在支付系统中&#xff0c;订单支付的超时自动撤销是一个非常常见的业务场景。通常用户未在规定时间内完成支付&#xff0c;系统会自动取消订单&#xff0c;释放相应的资源。本文将通过利用 RabbitMQ 的 死信队列&#xff08;Dead Letter Queue, DLQ&#xff09;来实现…...

pytest+request+yaml+allure搭建低编码调试门槛的接口自动化框架

接口自动化非常简单&#xff0c;大致分为以下几步&#xff1a; 准备入参调用接口拿到2中response&#xff0c;继续组装入参&#xff0c;调用下一个接口重复步骤3校验结果是否符合预期 一个优秀接口自动化框架的特点&#xff1a; 【编码门槛低】&#xff0c;又【能让新手学到…...

Elasticsearch实战指南:从入门到高效使用

Elasticsearch实战指南&#xff1a;从入门到高效使用 1. 引言&#xff1a;Elasticsearch是什么&#xff1f; Elasticsearch是一个分布式、RESTful风格的搜索和分析引擎&#xff0c;广泛应用于全文搜索、日志分析、实时数据分析等场景。它的核心特点包括&#xff1a; 高性能&…...

Open FPV VTX开源之嵌入式OSD配置

Open FPV VTX开源之嵌入式OSD配置 1. 源由2. 安装3. 配置步骤一&#xff1a;备份/etc/telemetry.conf步骤二&#xff1a;修改/etc/telemetry.conf步骤三&#xff1a;配置时区步骤四&#xff1a;重启摄像头 4. 实测5. 参考资料 1. 源由 穿越机模拟图传延迟通常在10ms左右。 最…...

2Hive表类型

2Hive表类型 1 Hive 数据类型2 Hive 内部表3 Hive 外部表4 Hive 分区表5 Hive 分桶表6 Hive 视图 1 Hive 数据类型 Hive的基本数据类型有&#xff1a;TINYINT&#xff0c;SAMLLINT&#xff0c;INT&#xff0c;BIGINT&#xff0c;BOOLEAN&#xff0c;FLOAT&#xff0c;DOUBLE&a…...

计算机网络之---公钥基础设施(PKI)

公钥基础设施 公钥基础设施&#xff08;PKI&#xff0c;Public Key Infrastructure&#xff09; 是一种用于管理公钥加密的系统架构&#xff0c;它通过结合硬件、软件、策略和标准来确保数字通信的安全性。PKI 提供了必要的框架&#xff0c;用于管理密钥对&#xff08;包括公钥…...

EF Core执行原生SQL语句

目录 EFCore执行非查询原生SQL语句 为什么要写原生SQL语句 执行非查询SQL语句 有SQL注入漏洞 ExecuteSqlInterpolatedAsync 其他方法 执行实体相关查询原生SQL语句 FromSqlInterpolated 局限性 执行任意原生SQL查询语句 什么时候用ADO.NET 执行任意SQL Dapper 总…...

GaussDB分布式数据倾斜处理

常规数据倾斜巡检 在库中表个数少于1W的场景&#xff0c;直接使用倾斜视图查询当前库内所有表的数据倾斜情况 SELECT * FROM pgxc_get_table_skewness ORDER BY totalsize DESC;在库中表个数非常多&#xff08;至少大于1W&#xff09;的场景&#xff0c;因PGXC_GET_TABLE_SKEWN…...

代码随想录Day34 | 62.不同路径,63.不同路径II,343.整数拆分,96.不同的二叉搜索树

代码随想录Day34 | 62.不同路径,63.不同路径II,343.整数拆分,96.不同的二叉搜索树 62.不同路径 动态规划第二集&#xff1a; 比较标准简单的一道动态规划&#xff0c;状态转移方程容易想到 难点在于空间复杂度的优化&#xff0c;详见代码 class Solution {public int uniq…...

vue.js辅助函数-mapMutations

在Vue.js中&#xff0c;使用辅助函数可以更方便地使用Vuex的mutation。而mapMutations就是Vuex提供的一个辅助函数&#xff0c;它可以将mutation映射到组件的methods中&#xff0c;使得我们可以在组件中直接调用mutation&#xff0c;而不需要手动进行commit。 mapMutations函数…...

Vue3组件设计模式:高可复用性组件开发实战

Vue3组件设计模式:高可复用性组件开发实战 一、前言 在Vue3中&#xff0c;组件设计和开发是非常重要的&#xff0c;它直接影响到应用的可维护性和可复用性。本文将介绍如何利用Vue3组件设计模式来开发高可复用性的组件&#xff0c;让你的组件更加灵活和易于维护。 二、单一职责…...

PHP 8.4 安装和升级指南

文章精选推荐 1 JetBrains Ai assistant 编程工具让你的工作效率翻倍 2 Extra Icons&#xff1a;JetBrains IDE的图标增强神器 3 IDEA插件推荐-SequenceDiagram&#xff0c;自动生成时序图 4 BashSupport Pro 这个ides插件主要是用来干嘛的 &#xff1f; 5 IDEA必装的插件&…...

什么是 OpenResty

1、OpenResty简介 1.1 了解OpenResty OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台&#xff0c;其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。 简单地说OpenRes…...

Windows图形界面(GUI)-QT-C/C++ - QT控件创建管理初始化

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 控件创建 包含对应控件类型头文件 实例化控件类对象 控件设置 设置父控件 设置窗口标题 设置控件大小 设置控件坐标 设置文本颜色和背景颜色 控件排版 垂直布局 QVBoxLayout …...

【计算机网络】lab8 DNS协议

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;计算机网络_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2.…...

了解linux中的“of_property_read_u32()”

of_property_read_u32(node, "post-pwm-on-delay-ms",&data->post_pwm_on_delay); /*根据"post-pwm-on-delay-ms"&#xff0c;从属性中查找并读取一个32位整数*/ /*读到一个32位整数,保存到data->post_pwm_on_delay中*/ of_property_read_u32…...

iOS - Objective-C 底层中的内存屏障

1. 基本实现 // objc-os.h 中的内存屏障实现 #define OSMemoryBarrier() __sync_synchronize()// ARM 架构特殊处理 static ALWAYS_INLINE void OSMemoryBarrierBeforeUnlock() { #if defined(__arm__) || defined(__arm64__)OSMemoryBarrier(); #endif } 2. 解锁前的内存屏…...

阿里云服务器扩容系统盘后宝塔面板不显示扩容后的大小

解决方法步骤&#xff1a; 1. yum install cloud-utils-growpart xfsprogs -y 2.growpart /dev/vda 3 扩容系统盘的第3个分区 主要是这个命令1 3. fdisk -l 4. df -h 5. xfs_growfs /dev/vda3 主要是这个命令2 主要使用 df -Th 这个命令查看对应的文件系统类型 (1)、ext…...

c语言——【linux】多进程编程 【进程的创建,相关shell指令,进程状态切换,回收资源,守护进程等】

1.思维导图 2.进程的创建 函数原型&#xff1a;pid_t fork(void); 功能描述&#xff1a;以当前进程为父进程&#xff0c;创建一个子进程 进程链和进程扇的创建 3.多进程具体使用 3.1进程替换 exec 函数一族 int execl(const char *path, const char *arg, ... /* (char *) N…...

macos 搭建 ragflow 开发环境

ragflow 是一个很方便的本地 RAG 库。本文主要记录一下在本机的部署过程 1、总体架构说明 开发环境&#xff1a;macbook pro&#xff08;m1&#xff09;&#xff0c;16G内存 512G固态 因本机的内存和硬盘比较可怜&#xff0c;所以在服务器上部署基础 docker 包&#xff0c;…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量&#xff1a;setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...