SpringBoot项目中遇到的订单支付超时未支付关闭订单的解决方案

news2025/1/15 22:34:17

1、扫表轮循

定时任务 => 获取数据 => 数据层 => 筛选出过期的数据 => 批量关闭超时订单

在这里插入图片描述

优点:实现简单、适用于小项目、数据量比较少
缺点:订单量过大的时候查询和修改数据库压力大、服务器内存消耗大、IO瓶颈

2、Redis懒删除

用户获取订单信息 => 判断是否过期 => 关闭超时订单

在这里插入图片描述

优点:实现简单
缺点:必须要用户查询该条订单信息的时候才会触发

3、RabbitMQ或Kafka延迟消息队列

用户下单 => 发送延迟消息 => 延迟队列存储 => 到期消费 => 检测支付状态 => 未支付? => 关闭超时订单

在这里插入图片描述

缺点:需要引入消息中间件
优点:随时能从队列里面移除实时取消的订单、不会占用应用服务器的资源、异步化处理

SpringBoot + RabbitMQ延迟消息队列实现(死信队列)

死信,顾名思义就是无法被消费的消息。一般来说,producer 将消息投递到 broker 或者直接到queue 里了,consumer 从 queue 取出消息进行消费,但某些时候由于特定的原因导致queu 中的某些消息无法被消费,这样的消息如果没有后续的处理,就变成了死信,有死信自然就有了死信队列。

而由于TTL(生存时间)过期导致的死信,就是我们实现延迟队列的的方式。

也就是说我们的正常的队列中某个值达到了特定的时间,过期了,这时候这个值将会到达死信队列中去,我们只需要监听死信队列就可以操作订单支付超时自动关闭的业务了。

1、pom.xml中引入RabbitMQ

<!-- springboot集成rabbitMQ -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

在这里插入图片描述

2、application.yml中配置RabbitMQ

#rabbitmq配置
rabbitmq:
  host: 192.168.1.100
  port: 5672
  username: guest
  password: guest
  virtual-host: /

在这里插入图片描述

3、配置RabbitMQConfig交换机和队列

package com.ckm.yangle.rabbitmqjob.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

//rabbitMQ绑定交换机 / 队列
@Configuration
public class RabbitMQConfig {

    //========================================================订单未支付定时关闭RabbitMQ Queue========================================================//

    //订单交换机
    @Bean
    public DirectExchange directExchangeOrder(){
        return new DirectExchange("order-direct-exchange");
    }
    //订单队列
    @Bean
    public Queue orderDataChangeQueue() {

        Map<String, Object> args = new HashMap<>(3);
        //声明当前队列绑定到死信交换机
        args.put("x-dead-letter-exchange", "order-dead-direct-exchange");
        //声明当前队列绑定到死信路由 key
        args.put("x-dead-letter-routing-key", "routing-order-dead");
        //声明队列的 TTL 过期时间 设置队列的过期时间为10秒(10000),单位为毫秒
        args.put("x-message-ttl", 10000);
        return QueueBuilder.durable("order-queue").withArguments(args).build();

    }
    //队列绑定交换机
    @Bean
    public Binding orderBindExchange(Queue orderDataChangeQueue, DirectExchange directExchangeOrder) {
        return BindingBuilder.bind(orderDataChangeQueue).to(directExchangeOrder).with("routing-order");
    }


    // 声明 死信队列交换机 order-dead-direct-exchange
    @Bean
    public DirectExchange directExchangeOrderDead() {
        return new DirectExchange("order-dead-direct-exchange");
    }
    //声明死信队列 order-dead-queue
    @Bean
    public Queue orderDeadDataChangeQueue() {
        return new Queue("order-dead-queue",true);
    }
    //声明死信队列绑定死信交换机
    @Bean
    public Binding orderDeadBindExchange(Queue orderDeadDataChangeQueue, DirectExchange directExchangeOrderDead) {
        return BindingBuilder.bind(orderDeadDataChangeQueue).to(directExchangeOrderDead).with("routing-order-dead");
    }
}

在这里插入图片描述

4、监听RabbitMQ死信队列消费者消费

package com.ckm.yangle.rabbitmqjob.order;

import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;

@Slf4j
@Component
public class RabbitMQDataSyncListenerOrder {
    @RabbitListener(queues = "order-dead-queue")
    public void receiveD(Message message, Channel channel) throws IOException {
        String msg = new String(message.getBody());
        log.info("当前时间:{},收到死信队列信息:{}", new Date().toString(), msg);
    }
}

在这里插入图片描述

5、在业务中生产者生产消息

log.info("当前时间:{},发送一条信息给一个 TTL 队列:{}", new Date(), "消息测试");
rabbitTemplate.convertAndSend("order-direct-exchange", "routing-order", "消息来自 ttl 为 30S 的队列: " + "消息测试");

在这里插入图片描述

6、测试结果

业务执行生产消息 => 到达过期时间 => 监听到死信队列

在这里插入图片描述

4、Redis过期监听机制

用户下单 => 发送Redis消息 => Redis Key过期时间 => 过期回调 => 检测支付状态 => 未支付?关闭超时订单

在这里插入图片描述

缺点:订单量过大非常消耗Redis服务器资源
优点:不会占用应用服务器的资源、应用的宕机不会对Redis产生影响、Redis过期时间准确度高

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/415782.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java SSM选房管理系统idea开发mysql数据库java编程计算机网页源码maven项目

一、源码特点 SSM选房管理系统是一套完善的完整医院类型系统&#xff0c;结合SSM&#xff08;SpringSpringMVCMyBatis&#xff09;框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系…

Twitter的推荐系统开源了,Twitter的推荐系统是什么样的呢?Twitter推荐系统的架构说明

Twitter的推荐系统开源了&#xff0c;Twitter的推荐系统是什么样的呢&#xff1f;Twitter推荐系统的架构说明01. Twitter的推荐系统是什么样的&#xff1f;02. Candidate Sources2.1 In-Network Source2.2 Out-of-Network Sources03. Ranking04. Heuristics, Filters, and Prod…

VR虚拟核电设备拆除模拟培训降低风险

核电站设备拆除是一项高危、复杂的任务&#xff0c;因此进行安全、有效的培训至关重要。为此&#xff0c;将VR虚拟现实技术应用于核电厂中&#xff0c;通过100%模拟还原真实的拆除操作场景&#xff0c;广泛应用到核电厂展示、巡检和拆除等环节中&#xff0c;极大提高了生产效率…

单片机学习之中断与定时/计数器

记录学习中断的使用。 1. 使用工具 使用开发板&#xff1a; 普中科技开发板 编译软件&#xff1a; keil 2. 复习中断及相关概念 CPU在处理 事件A 时&#xff0c;中断源 发出中断请求&#xff0c;请求cpu处理事件B &#xff0c;cpu 中断 当前工作&#xff0c;转去处理事件B&a…

HTML5 视频 Video

文章目录HTML5 视频 VideoWeb站点上的视频浏览器支持HTML5 (视频)- 如何工作视频格式与浏览器的支持视频格式HTML5 \<video> - 使用 DOM 进行控制HTML5 Video 标签HTML5 视频 Video 很多站点都会使用到视频. HTML5 提供了展示视频的标准。 Web站点上的视频 直到现在&am…

详解数据恢复多少一个g以及如何恢复

整理电脑硬盘数据的时候不小心删除了重要的文件该如何么恢复呢?硬盘修复数据恢复价格都爱的贵不贵?今天小编就来给大家重点当前市场上硬盘数据恢复的价格相关内容&#xff0c;那么数据恢复多少钱一个g呢?下面就来给大家揭晓一下数据恢复多少钱一个g以及如何恢复。 工具/原料…

全国青少年电子信息智能创新大赛(决赛)python·模拟三卷,含答案解析

全国青少年电子信息智能创新大赛(决赛) python 模拟三卷 一、程序题 第一题:描述 现有 n 个人依次围成一圈玩游戏,从第 1 个人开始报数,数到第 m 个人出局,然 后从出局的下一个人开始报数,数到第 m 个人又出局,...,如此反复到只剩下 最后一个是胜利者。设 n 个人的编号…

常用 Composition API--工程文件及setup

官方文档: https://v3.cn.vuejs.org/guide/composition-api-introduction.html 分析工程结构 vue3新添加的东西或修改的内容 首先import { createApp } from vue引入的不再是Vue的构造函数了&#xff0c;而是一个createAPP的工厂函数&#xff0c;什么是工厂函数&#xff1f; …

【TimeSerias】Transformer

Sequence 1. rnn 和 cnn RNN 很难并行化CNN很难捕捉较远的信息 2. Self-attention 拿每个query q去对每个 key k做attention 计算输出 Self-attition 矩阵计算 qiWqaikiWkqiviWvaiQWqAKWkAVWvA(1.1)\begin{align*} q^i & W^q a^i \\ k^i & W^k q^i \\ v^i & W…

WordPress图片水印插件 Easy Watermark

1、概述 WordPress图片水印插件Easy Watermark 是一款实现上传图片自动添加水印LOGO功能的高效插件。当我们在WordPress网站后台上传图片文件到媒体库时&#xff0c;或者在发布文章上传图片时&#xff0c;Easy Watermark 都能为图片自动添加水印&#xff0c;同时&#xff0c;还…

《计算机网络-自顶向下》06. 链路层和局域网

文章目录链路层概述链路层提供的服务链路层在何处实现差错检测和纠正技术奇偶校验循环冗余检测多路访问协议信道划分协议随机接入协议时隙 ALOHAALOHA载波侦听多路访问 —— CSMA具有碰撞检测的载波侦听多路访问 —— CSMA/CDCSMA/CD 效率轮流协议DOCSIS&#xff1a;用于电缆因…

c++11 标准模板(STL)(std::stack)(五)

定义于头文件 <stack> template< class T, class Container std::deque<T> > class stack; std::stack 类是容器适配器&#xff0c;它给予程序员栈的功能——特别是 FILO &#xff08;先进后出&#xff09;数据结构。 该类模板表现为底层容器的包…

C++实现:学生管理系统(详细解析)

目录 1.题目要求 2.需求分析 3.整体设计 4.详细设计 主函数设计 学科科目类 主菜单 读取文件与写入文件 效果如下 添加学生信息 删除学生信息 ​编辑 修改学生信息 显示信息列表 显示学生列表 将学生列表按学号升序排列 将学生列表按平均分降序排列&#xff0c;平…

文件操作File类,OutputStream、InputStream、Reader、Writer的用法

文章目录File 类OutputStream、InputStreamInputStreamOutputStreamReader、WriterReaderWriter注意事项简单模拟实战File 类 Java标准库中提供的File类是对硬盘上的文件的抽象&#xff0c;每一个File对象代表了一个文件&#xff0c;因为文件在硬盘上存储&#xff0c;而直接操…

4月11日作业修订

A.这主要看你互斥锁锁的资源是那部分的&#xff0c;如果是进程内资源&#xff0c;则可以实现同一进程不同线程之间的互斥&#xff0c;而如果将共享内存作为互斥锁进行操作则可以实现不同进程之间的互斥。 B.这是必然的&#xff0c;加锁是为了防止数据的二义性 C.信号量同时使…

代码规范(以后会补充)

目录 为什么要规范代码 不规范的代码有什么特点 ​编辑 不规范的坏处 规范代码是什么样的 如何规范代码 1.代码中不要出现莫名其妙的数字 2.深度嵌套 3.注释 4.避免创建大函数 5.重复代码 6.变量命名 7.函数命名 8.命名时注意动词的使用 9. 常量值所有都大写 10. 避免变…

Bossies 2016:最佳开源大数据工具

导读在今年的 Bossie开源大数据工具中&#xff0c;你会发现最新最好的方法是利用大型集群进行索引、搜索、图形处理、流处理、结构化查询、分布式OLAP和机器学习&#xff0c;因为众多处理器和RAM可降低工作量级。 处理大数据可能会遇到各种各样的问题&#xff0c;目前没有任何工…

SpringMVC简介及入门

SpringMVC SpringMVC简介 一、三层架构和MVC 1、三层架构概述 &#xff08;1&#xff09;开发架构&#xff1a;一是 C/S 架构 (客户端/服务器)&#xff0c;二是B/S架构&#xff08;浏览器/服务器)。在JavaEE开发中&#xff0c;几乎全部是基于 B/S架构的开发。在B/S 架构中&…

最简单IDEA社区版构建SpringBoot项目

一、环境准备 IDEA Community Edition jdk8 maven 二、下载SpringBoot项目 https://start.spring.io/ 项目名称自己修改下。 点击ADD DEPENDENCIES&#xff0c;添加Web依赖。 下载构建好的SpringBoot项目的压缩包 三、idea中打开SpringBoot项目 使用maven加载依赖。 四、测…

【数据库原理 • 三】关系数据库标准语言SQL

前言 数据库技术是计算机科学技术中发展最快&#xff0c;应用最广的技术之一&#xff0c;它是专门研究如何科学的组织和存储数据&#xff0c;如何高效地获取和处理数据的技术。它已成为各行各业存储数据、管理信息、共享资源和决策支持的最先进&#xff0c;最常用的技术。 当前…