订单到期关闭如何实现(延迟场景处理)

文章目录

    • 概述
    • 种处理方案
    • 任务调度实现(定时任务)
    • 基于redis 如何实现
      • 1redis过期key实现(键通知机制)
      • 基于redis延迟队列
      • Redisson实现一个延迟队列
    • 基于MQ的延迟队列实现

概述

订单30分钟未支付自动取消怎么实现
日常开发中,我们经常遇到这种业务场景,如:外卖订单超 30 分钟未支付,则自动取订单;用户注册成功 15 分钟后,发短信息通知用户等等。这就延时任务处理场景。
在电商,支付等系统中,一设都是先创建订单(支付单),再给用户一定的时间进行支付,如果没有按时支付的
话,就需要把之前的订单(支付单)取消掉。这种类以的场景有很多,还有比如到期自动收货,超时自动退款,下
单后自动发送短信等等都是类似的业务问题。

种处理方案

定期轮询(数据库定时任务 Quartz)
JDK DelayQueue
JDK Timer
ScheduledExecutorService 周期性线程池
时间轮(kafka)
时间轮(Netty的HashedWheelTimer)

redis过期监听
redis的zset
redisson
zookeeper之curator
kafka和rocketmq延迟消息
RabbitMQ(延迟队列和死信队列)
Quartz,xxljob等定时任务框架
Koala(考拉)
JCronTab(仿crontab的java调度器)
SchedulerX(阿里)
有赞延迟队列

任务调度实现(定时任务)

使用 Java 定时任务框架(如 Quartz、Spring Task 等)创建一个定时任务,定时检查订单的到期时间。
在订单创建时,将订单的到期时间保存在数据库中或缓存中。
在定时任务中,获取当前时间,查询数据库或缓存,找出已到期但尚未关闭的订单。
针对每个到期订单,执行关闭订单的操作,例如更新订单状态为关闭或发送关闭订单的消息。
定时任务可以根据需求设置执行频率,以保证及时关闭到期订单。
缺点:效率非常低,消耗服务器性能,对数据库造成压力,

基于redis 如何实现

redis过期监听
redis的zset
redisson

1redis过期key实现(键通知机制)

1)用户下单的时候,生成一个令牌(有效期)30分钟,存放到我们redis;
2)redis.set(orderToken ,orderID) 下单时候存放到redis,并存储id入库,30分钟过期,
3)redis客户端监听,过期获取到orderId,拿orderId去查订单,没有支付则,订单关闭,库存增加
缺点: 1) 非常冗余 ,会在表中存放一个冗余字段 2) 键通知机制是一种并不可靠的消息机制,如果系统需要需要很好的可靠性,那么它并不是一种很好的选择。

基于redis延迟队列

优点:可以满足吞吐量
缺点:存在任务丢失的风险(当 Redis 实例挂了的时候)。因此,如果对性能要求比较高,同时又能容忍少数情况下任务的丢失,那么可以使用这种方式来实现。
使用 sortedset,拿时间戳作为score,消息内容作为 key 调用 zadd 来生
产消息,消费者用 zrangebyscore 指令获取 N 秒之前的数据轮询进行处理。
Redis延迟队列是一种常用的消息队列模式,用于延迟处理任务或消息。其原理通常基于两个主要组件:有序集合(Sorted Set)和定时任务轮询。

  1. 有序集合(Sorted Set):
    ○ Redis中的有序集合是一种数据结构,其中的每个成员都关联了一个分数(score)。有序集合的特性之一是按照分数从小到大排序。在延迟队列中,可以将消息或任务的执行时间作为分数,将消息内容作为成员存储在有序集合中。
  2. 定时任务轮询:
    ○ 定时任务轮询是一种机制,用于定期检查有序集合中是否有到期的任务或消息。通过定期轮询有序集合,可以检查是否有任务的执行时间已到达,从而将其取出并执行。

Redisson实现一个延迟队列

Redisson是一个基于Redis的分布式Java对象和服务框架,它提供了一系列的高级特性,如分布式对象、分布式锁、分布式消息队列等。其中,分布式消息队列可以非常方便地实现延迟队列。
基于Redisson实现延迟队列的一种常见方式是使用Redis的sorted set来存储任务,并使用Redis的定时器功能触发任务的执行。具体实现步骤如下:

  1. 定义一个Java类来表示任务,该类需要包含任务的执行时间、任务内容等属性。
  2. 使用Redisson获取一个RedissonClient对象,该对象用于与Redis进行交互。
  3. 创建一个RedissonDelayedQueue类,该类包含以下几个方法:
    addTask:将一个任务添加到delayed queue中,使用Redis的zadd命令将任务的执行时间作为score,任务内容作为value添加到sorted set中。
    removeTask:从delayed queue中删除指定的任务,使用Redis的zrem命令从sorted set中删除指定的value。
    pollTask:从delayed queue中取出最早可执行的任务,使用Redis的zrangeByScore命令获取score小于当前时间的最小value,并使用Redis的zrem命令删除该value。
  4. 使用Redis的定时器功能,每隔一段时间(例如1秒钟),调用RedissonDelayedQueue的pollTask方法,将需要执行的任务取出并执行。
    这样,就可以基于Redisson实现一个简单的延迟队列了。需要注意的是,这种方式只适用于任务数量较少的情况,如果任务数量较大,可以考虑使用更高级的方案,比如使用Redis的Lua脚本等。

基于MQ的延迟队列实现

  1. 延迟队列方案:
    使用消息队列(如 RabbitMQ、Kafka 等)创建一个延迟队列,并设置过期时间为订单的到期时间。
    在订单创建时,将订单信息发送到延迟队列。
    消费者监听延迟队列,当订单到期时,消费者从队列中接收到该订单并执行关闭操作。
    可以使用单个消费者或多个消费者来处理到期订单,实现并行处理和提高吞吐量。
    RabbitMQ的延迟队列,使用过期时间+死信队列来实现
    实现原理:
    1)下单投放消息到 A交换机(过期时间30分钟),将 aa队列绑定到该死信交换机A, 不设置aa队列的消费者(故此消息一直未消费)
    2)30分钟后,过期,消息投递到死信交换机,死信队列的消费者消费死信消息, 判断订单id是否支付,执行业务逻辑,支付->return 。未支付->关闭订单,返还库存。

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

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

相关文章

2. Linux进程管理

2. 进程管理 2.1 Linux进程 进程是程序执行时的一个动态实体,包含程序计数器、全部CPU 寄存器的值和进程堆栈中存储着的一些临时数据,如子程序参数、返回地址及变量等,反映的是当前处理器的活动状态。 而程序是仅包含指令和数据的一段静态代…

【Appium UI自动化】pytest运行常见错误解决办法

通过Appium工具录制代码在pycharm上运行报错: 错误一: 1.提示 setup() 方法运行 error failed 解决办法:未创建 init __ 方法,创建一个空的__init.py文件就解决了。 原因: 错误二: 2.运行代码&#xff…

Linux之ACL权限管理

文章目录 1.ACL权限介绍二、操作步骤1. 添加测试目录、用户、组,并将用户添加到组2. 修改目录的所有者和所属组3. 设定权限4. 为临时用户分配权限5. 验证acl权限6. 控制组的acl权限 1.ACL权限介绍 每个项目成员有一个自己的项目目录,对自己的目录有完全…

构建生物医学知识图谱from zero to hero (4):通过Neo4j构建知识图谱

图数据库是一种专门用于存储图形数据的 NoSQL 数据库。与传统的关系型数据库和其他 NoSQL 数据库不同,图数据库利用图形数据模型来存储和管理数据。图形数据模型由节点和边组成,节点代表实体,边代表实体之间的关系。例如,在社交网络中,用户可以表示为节点,朋友关系可以表…

xff注入 [CISCN2019 华东南赛区]Web111

打开题目 看见smarty 想到模板注入 又看见ip 想到xff注入 一般情况下输入{$smarty.version}就可以看到返回的smarty的版本号。该题目的Smarty版本是3.1.30 在Smarty3的官方手册里有以下描述: Smarty已经废弃{php}标签,强烈建议不要使用。在Smarty 3.1&#xff…

C# OpenVINO 百度PaddleSeg实时人像抠图PP-MattingV2

目录 效果 项目 代码 下载 C# OpenVINO 百度PaddleSeg实时人像抠图PP-MattingV2 效果 项目 代码 using OpenCvSharp; using Sdcb.OpenVINO; using System; using System.Diagnostics; using System.Drawing; using System.Security.Cryptography; using System.Text; us…

SparkSQL学习03-数据读取与存储

文章目录 1 数据的加载1.1 方式一:spark.read.format1.1.1读取json数据1.1.2 读取jdbc数据 1.2 方式二:spark.read.xxx1.2.1 读取json数据1.2.2 读取csv数据1.2.3 读取txt数据1.2.4 读取parquet数据1.2.5 读取orc数据1.2.6 读取jdbc数据 2 数据的保存2.1…

SmartX 携手 openGauss 社区发布联合方案评测与性能最佳实践

近日,北京志凌海纳科技有限公司(以下简称 “SmartX”)携手 openGauss 社区完成了 openGauss 数据库基于 SmartX 超融合平台(SMTX OS)和 SmartX 分布式存储平台(SMTX ZBS)的性能测试和调优。 结果…

JavaScript中的可选链——通过示例解释

JavaScript开发经常涉及导航嵌套对象,这可能很麻烦且容易出错,特别是在处理null或undefined值时。可选链是现代JavaScript语法中的一个改革性特性。 在本文中,我们将通过实际示例探讨可选链,演示它如何简化代码并使开发更加高效。…

MySQL数据库基础(十三):关系型数据库三范式介绍

文章目录 关系型数据库三范式介绍 一、什么是三范式 二、数据冗余 三、范式的划分 四、一范式 五、二范式 六、三范式 七、总结 关系型数据库三范式介绍 一、什么是三范式 设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库&…

代码随想录算法训练营第五十九天|

583. 两个字符串的删除操作 本题和动态规划:115.不同的子序列 相比,其实就是两个字符串都可以删除了,情况虽说复杂一些,但整体思路是不变的。 代码随想录 class Solution {public int minDistance(String word1, String word2) {…

流畅的Python(十一)-从协议到抽象基类

一、核心要义 主要讨论Python中的接口,所谓接口就是类实现或继承的一套公开(按照定义,受保护的属性和私有属性不在接口中)属性和方法,包括特殊方法,如__getitem__或__add__等。Python有两套规范接口的方式: 1. 鸭子类型和协议,这…

几种后端开发中常用的语言。

几种后端开发中常用的语言。 C/C 语言 C 语言最初是用于系统开发工作,特别是组成操作系统的程序。由于 C 语言所产生的代码运行速度与汇编语言编写的代码运行速度几乎一样,所以采用 C 语言作为系统开发语言。目前,C 语言是最广泛使用的系统…

MongoDB聚合运算符:$atan2

$atan2用来计算反正切&#xff0c;返回指定表达式的反正切值&#xff0c;与$antan的区别主要是参数不同。 语法 { $atan2: [<expression1>, <expression1>] }<expression>为可被解析为数值的表达式$atan2返回弧度&#xff0c;使用$radiansToDegrees运算符可…

数据结构与算法-常用排序算法

一、常用排序说明 当涉及排序算法时&#xff0c;理解每个算法的工作原理、时间复杂度和空间复杂度是至关重要的。下面对常用排序算法进行详细说明&#xff1a; 1、冒泡排序&#xff08;Bubble Sort&#xff09;&#xff1a; 工作原理&#xff1a;比较相邻的元素并交换&am…

python bug与debug

一、什么是bug&#xff08;软件缺陷&#xff09;&#xff1f; 产品说明书中规定要做的事情&#xff0c;而软件没有实现。 产品说明书中规定不要做的事情&#xff0c;而软件确实现了。 产品说明书中没有提到过的事情&#xff0c;而软件确实现了。 产品说明书中没有提到但是必…

跨语言的序列化与反序列化

在Java中实现跨语言的序列化与反序列化通常可以采用以下几种方式 使用标准的跨语言序列化格式 可以选择使用一些标准的跨语言序列化格式,例如JSON、XML、Protocol Buffers(ProtoBuf)等。这些格式都是跨语言的,可以方便地在不同的编程语言之间进行数据交换。在Java中,可以…

紫光同创初使用

芯片PGC2KG-6LPG144 1、安装好软件接&#xff0c;加载license,有两个&#xff0c;与电脑MAC地址绑定的 2、正常使用后&#xff0c;新建个工程&#xff0c;配置管脚Tools→UCE 3、程序中有些信号被软件认为是时钟信号&#xff0c;会报错&#xff08;时钟输入I0约束在非专用时钟…

LeetCode--代码详解 78.子集

78.子集 题目 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[],[1…

Python爬虫-使用代理伪装IP

爬虫系列&#xff1a;http://t.csdnimg.cn/WfCSx 前言 我们在做爬虫的过程中经常会遇到这样的情况&#xff0c;最初爬虫正常运行&#xff0c;正常抓取数据&#xff0c;一切看起来都是那么的美好&#xff0c;然而一杯茶的功夫可能就会出现错误&#xff0c;比如 403 Forbidden&…