限时订单实现方案(DelayQueue、ActiveMq)
原文链接:http://www.studyshare.cn/blog-front/blog/details/1132
一、在各种电商网站下订单后会保留一个时间段,时间段内未支付则自动将订单状态设置为已过期。
二、解决方案
1、轮询数据库:实现一个定时器,每隔一段时间去检查一遍数据库里的所有订单,查看其状态是否是未支付并且已经到期。并修改这些数据的状态为已过期。
优点:方法简单,容易实现
缺点:订单状态处理不及时,轮询数据库的次数中可能很多都并没有修改订单(做的无用功),数据库频繁多次被连接浪费数据库资源开销。
因此以上方式实际开发中基本不予采用。开发中真正实现限时订单采用以下两种方案:
2、Java本身的解决方案--DelayQueue,延时队列
核心思想如图:
(1)、用户下单,保存订单到数据库的同时,将该订单以及订单的过期时间推入DelayQueue
(2)、启动一个检查订单到期的线程,该线程使用delayQueue的take()方法获取到期订单,该方法为阻塞方法,如果当前没有到期订单,该方法会一直阻塞等待,直到获取到订单后继续往下执行。
(3)、当take()获取到一个到期订单后,该线程按获取到的订单的id去数据库查询订单并去检查订单状态,如果为未支付,则将状态修改为已过期
2.1、SpringBoot框架下代码实现
延时队列实体Bean
延时订单业务处理接口
延时订单业务处理实现类
如果我们只实现了以上的代码,会存在一个很严重的问题,因为延时订单是存在DelayQueue中的,而DelayQueue是存在内存中的,那么当系 统重启后,DelayQueue中的数据就被清空了,因此当系统重新启动的时候,需要在订单的实现类中去做一个检索数据库订单的操作,将已过期未支付的设置为已过期,将未过期未支付的重新推入DelayQueue队列中。代码如下:
@PostConstruct 注解不重复解释,上面代码中有注释
2.2、JFinal框架下代码实现
由于项目中接口工程使用的是JFinal框架,SpringBoot框架下实现限时订单很简单,而JFinal框架下实现有一点小麻烦,特别在此进行分享
(1)ItemVo类和SpringBoot下的一模一样。不再重复贴代码
(2)延时订单业务接口
(3)延时订单业务处理实现类
首先了解一下,在JFinal框架下会有一个初始化类JFinalConfig,继承该类可以做项目的一些初始化操作
该类有两个方法:
afterJFinalStart() :当JFinal框架初始化完成后执行,仅执行一次
beforeJFinalStop() :当JFinal框架关闭之前执行,仅执行一次
那么我们的延时订单线程初始化与系统重启后检测数据库订单的操作就可以放到afterJFinalStart() 里面进行执行
系统关闭线程中断执行代码:
以上就完整实现了限时订单的功能。
3、ActiveMq消息中间件实现方案
使用DelayQueue方案适合在单台服务器上,如果在分布式环境下,DelayQueue方案则还需要进行改进,存在的问题就是多个服务器会抢夺同一个订单,解决方案就是分区处理,每个服务器只负责自己的订单,不管其他服务器上的订单。
使用DelayQueue的方案在功能上比较好的实现了限时订单的功能,但是可扩展性和伸缩性并不好,那么接下来使用ActiveMq实现,既能实现功能,也能更好的扩展和伸缩(消息中间件的特性就是实现系统的解耦)
实现步骤:
1、用户下单保存到数据库的同时使用消息生产者发送一条消息到ActiveMq消息队列,注意:并不是调用send就马上发送,而是根据过期时间进行延迟发送。时间到期了才会发送这条消息到消息队列中。
2、当消息队列收到该消息的时候,将消息转发给订阅了该队列的消费者,消费者收到消息就去做订单状态检查
(1)、接口实现类
(2)、消息生产者--发送订单到期的消息到消息队列(按过期时间延迟发送)
(3)、消息消费者--修改订单过期状态
以上三个类就是使用ActiveMq消息中间件实现限时订单的所有代码。调用代码很简单就是保存订单的同时将消息发送到消息队列,不在赘述。
更多深度技术好文:http://www.studyshare.cn/blog-front//index
限时订单实现方案(DelayQueue、ActiveMq)的更多相关文章
- Dubbo学习系列之七(分布式订单ID方案)
既然选择,就注定风雨兼程! 开始吧! 准备:Idea201902/JDK11/ZK3.5.5/Gradle5.4.1/RabbitMQ3.7.13/Mysql8.0.11/Lombok0.26/Erl ...
- 并发容器之阻塞队列DelayQueue的使用案例及源码分析
原文连接:(http://www.studyshare.cn/blog-front//blog/details/1167/0 ) 一.队列及阻塞队列概念 1.队列:是一种特殊线性表,特殊之处在于操作是 ...
- ActiveMQ基础教程----简单介绍与基础使用
概述 ActiveMQ是由Apache出品的,一款最流行的,能力强劲的开源消息总线.ActiveMQ是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,它非常快速,支持多 ...
- RabbitMQ实现订单超时案例
前言 人间清醒 目录 前言 业务场景 JUC(DelayQueue)方案 DelayQueue简介 JUC DelayQueue实现订单超时案例代码 案例代码 Redis Key过期事件方案 简介 R ...
- 快递查询api(多接口方案)
/** 本环境使用php+smarty,结合两种快递api调取快递数据 * 说明,先快递鸟调取数据,失败后再调取快递网的数据* 快递鸟 http://www.kdniao.com 快递网 http:/ ...
- 关于ActiveMQ的一点总结
ActiveMQ入门 作者:一路向北 摘要:本文主要讲述ActiveMQ的基本知识和使用方法,并简单结合spring使用ActiveMQ. 一.ActiveMQ特性和使用总览 企业消息软件从80年代起 ...
- ActiveMQ in Action(6) - Features
关键字: activemq 2.6 Features ActiveMQ包含了很多功能强大的特性,下面简要介绍其中的几个.2.6.1 Exclusive Consumer Queue中的消息 ...
- ActiveMQ入门介绍
1.JMS简介 JMS的全称是Java Message Service,即Java消息服务.它主要用于在生产者和消费者之间进行消息传递,生产者负责产生消息,而消费者负责接收消息.把它应用到实际的业务需 ...
- ActiveMQ消息持久化存储策略
ActiveMQ的内核是Java编写的,也就是说如果服务端没有Java运行环境ActiveMQ是无法运行的.ActiveMQ启动时,启动脚本使用wrapper包装器来启动JVM.JVM相关的配置信息在 ...
随机推荐
- Redis不支持ssl
一直在公司内部推荐redis做cache管理,今天偶然想起虽然C#没问题,可是c/c++没查过可不可行. 结果查了一下,还真tmd有问题,官方的c client版本只支持linux side的,根本没 ...
- Centos7快速安装docker
偶然间发现,docker的安装好容易啊 系统环境:centos7.3 yum源: docker:https://mirrors.aliyun.com/docker-ce/linux/centos/do ...
- iproute
iproute之tc命令翻译地址,man tc的翻译 http://blog.csdn.net/ysdaniel/article/details/7905879
- 给jumpserver双机配置glusterfs共享复制卷
为什么要使用glusterfs呢. 本身Haproxy+Keepalived对jumpserver进行了负载均衡和反向代理.但是真实的视频只会存储在一个节点上 否则播放视频的时候会出现找不到的情况 为 ...
- Docker系列(一)CentOS 6.5 离线安装、不升级内核
本特安装教程特点 1.由于是离线下载,需要提前下载好需要的依赖包 2.使用的版本为Centos6.5 3.不升级内核 4.提供异常解决方案. 安装过程 一.下载依赖包(使用能联网的节点) 依赖包可以自 ...
- Panel 中加载窗体
pnlMain.Controls.Clear(); ControlAnalyzer1 CA1 = new ControlAnalyzer1(); CA1.TopLevel = false; CA1.S ...
- Centos7下使用yum源安装zabbix Server
系统:Centos7 zabbix版本:4.2 一.Zabbix Server端 1.安装仓库 rpm -ivh https://repo.zabbix.com/zabbix/4.2/rhel ...
- QT心电图设计
不需要别的UI设置,直接放在QT文件中即可 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #includ ...
- php7 date函数警告去除
在代码头上添加 date_default_timezone_set("PRC");
- C# .NET newtonsoft.json 多版本冲突解决
A.DLL 引用了6.0 的 newtonsoft.json (V2 运行时),B.DLL 引用了10.0 的 newtonsoft.json (V4 运行时). 可以在.CONFIG RUNTIM ...