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

news/2024/7/8 4:20:54

文章目录

    • 概述
    • 种处理方案
    • 任务调度实现(定时任务)
    • 基于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://lihuaxi.xjx100.cn/news/2046352.html

相关文章

VSCode使用Remote-SSH连接服务器时报错:启动服务器失败问题

VSCode使用Remote-SSH连接服务器时报错:启动服务器失败问题 问题描述解决方法引用 问题描述 第一天上班,回来发现又不能使用VScode连不上服务器了,在「输出」栏出现了一直报 Waiting for server log… 的情况!本来以为是普通的连接…

线段树学习笔记 下

可持久化线段树 上面两篇是几年前写的,笔者今日才加以整理,如有错误请见谅。 线段树加上版本就是可持久化线段树。 Problem Intro 给定一个数组,只需要单点修改和单点查询,但要维护版本。 具体说,每一次操作可能从…

LabVIEW串口通信的激光器模块智能控制

LabVIEW串口通信的激光器模块智能控制 介绍了通过于LabVIEW的VISA串口通信技术在激光器模块控制中的应用。通过研究VISA串口通信的方法和流程,实现了对激光器模块的有效控制,解决了数据发送格式的匹配问题,为激光器模块的智能控制提供了一种…

Android和JS互相调用

JS调用Android: App.runMethod(, ); Android端配置JS调用的方法 webView.addJavascriptInterface(bleJavaScriptInterface, "App");public class BLEJavaScriptInterface {private MainActivity activity;private Handler handler;public void setActi…

Nodejs 第四十一章(项目架构MVC,IoC,DI)

到现在为止,我们学习了,express框架,编写接口,mysql数据库读写数据,knex,prisma ORM框架,现在是时候把这些组合到一起,并且实现一个类似于Nestjs或者java的SpringBoot的架构真正的去开发我们的n…

【前端素材】推荐优质后台管理系统Vuesy平台模板(附源码)

一、需求分析 后台管理系统在多个层次上提供了丰富的功能和细致的管理手段,帮助管理员轻松管理和控制系统的各个方面。其灵活性和可扩展性使得后台管理系统成为各种网站、应用程序和系统不可或缺的管理工具。下面详细分析后台管理系统的定义和功能: 1.…

Go基本数据类型

bool类型 布尔型的值只可以是常量 true 或者 false。⼀个简单的例⼦:var b bool true 数值型 1. 整数型 可以简单讲解⼀下⼆进制和位数的关系,以及int和uint的关系 int8 有符号 8 位整型 (-128 到 127) ⻓度:8bitint16 有符号 16 位整型…

harbor(docker仓库)仓库部署 - 高可用

harbor(docker仓库)仓库部署 - 高可用 1. harbor高可用1.1 方案说明1. 双主复制2. 多harbor实例共享后端存储 1.2 部署高可用(多harbor实例共享后端存储)1. 服务器划分2. 安装harbor(先部署一套Harbor,用于…