文档章节

Java秒杀系统实战系列~定时任务补充处理超时未支付的订单

稳杰
 稳杰
发布于 2019/08/07 09:55
字数 1349
阅读 159
收藏 0

摘要:

本篇博文是“Java秒杀系统实战系列文章”的第十一篇,本篇博文我们将借助定时任务调度组件来辅助“失效超时未支付的订单记录”的处理,用以解决上篇博文中采用“RabbitMQ死信队列失效处理超时未支付的订单”的瑕疵!

内容:

上篇文章我们介绍了如何采用消息中间件RabbitMQ的死信队列失效处理超时未支付的订单,实战完毕之后,相信各位小伙伴对死信队列应该有了一个初步的认识以及使用。在该业务场景中,虽然死信队列可以“近乎完美”地解决那样的需求,但是却仍然存在着一点瑕疵,即 “当许多订单记录恰好在某个TTL集中失效,准备交由RabbitMQ的死信队列进行处理时,此时恰好RabbitMQ的服务挂掉了。。。”

RabbitMQ的服务突然挂掉,将意味着在那个时候那些本该被失效处理的订单记录却迟迟没有得到处理(因为RabbitMQ已经不提供服务了!),虽然后面重启了RabbitMQ服务,消息也重新进行了处理,但是却有可能在这段时间内用户“重新下不了单”或者其他一些意想不到的问题!

各位小伙伴看到这里,估计应该明白个大概了!虽然会抱怨“他娘的,无缘无故,RabbitMQ的服务咋会挂掉”!抱怨归抱怨,现实却仍旧是现实,隐患仍然是存在的,那既然存在隐患,那就得找寻一些方法来解决。

本篇博文我们将采用“定时器”或者叫“定时任务调度”的方式来辅助处理,即我们会设定一下Cron时间,定时在数据库中轮询获取status=0(即状态为未支付)的订单,并更新失效掉那些时间已经超过了TTL的订单!(set status=-1)。下面我们进入代码实战环节:

(1)定时器的实现我们暂且采用一个比较简单的方式,即@Scheduled注解来实现,我们将所有的简单定时器的实现都放在SchedulerService服务类中,其完整源代码如下所示:

@Service
public class SchedulerService {
    private static final Logger log= LoggerFactory.getLogger(SchedulerService.class);

    @Autowired
    private ItemKillSuccessMapper itemKillSuccessMapper;

    @Autowired
    private Environment env;

    //定时获取status=0的订单并判断是否超过TTL,然后进行失效
    @Scheduled(cron = "0 0/30 * * * ?")
    public void schedulerExpireOrders(){
        try {
            List<ItemKillSuccess> list=itemKillSuccessMapper.selectExpireOrders();
            if (list!=null && !list.isEmpty()){
                //java8的写法
                list.stream().forEach(i -> {
                    if (i!=null && i.getDiffTime() > env.getProperty("scheduler.expire.orders.time",Integer.class)){
                        itemKillSuccessMapper.expireOrder(i.getCode());
                    }
                });
            }
        }catch (Exception e){
            log.error("定时获取status=0的订单并判断是否超过TTL,然后进行失效-发生异常:",e.fillInStackTrace());
        }
    }
}

其中的遍历,Debug是采用了Java8的Steam API。上述这种定时任务调度的写法简单粗暴,而且还快!(世上武功无坚不摧、无快不破!)但是,快归快,在这里还是需要提一点注意的地方。

(2)即如果在该项目有多个这样的定时任务,那么有一点值得注意的是:多个定时任务的执行时间Cron如果挨得很近,那么效率一定是瓶颈,这是因为如果只是上面那样写,那么始终只会有一个、单一的线程在执行上面的定时任务!

试想一下,如果有定时任务A、B、C都是每隔5分钟执行一次,那么很明显,将会有一些定时任务处于阻塞的状态而迟迟不能在规定的时间内执行完!

因此,为了解决此种“痛点”,我们需要加入一些自定义的配置,即针对“定时任务调度”我们加入“线程池”的配置,其完整的源代码如下所示,各位小伙伴可以写多几个定时器,然后观察控制台的输出信息,即可看到每个不同的定时任务采用了不同的线程执行。

/**
 * 定时任务多线程处理的通用化配置
 * @Author:debug (SteadyJack)
 * @Date: 2019/6/29 21:45
 **/
@Configuration
public class SchedulerConfig implements SchedulingConfigurer{
	//针对定时任务调度-配置多线程(线程池)
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(Executors.newScheduledThreadPool(10));
    }
}

(3)至此,关于定时任务辅助失效处理秒杀系统中“超时未支付的订单记录”的代码已经实战完毕了!可以调整一下Cron的取值,然后将整个系统运行在外置的Tomcat服务器,稍等片刻即可看到定时任务的执行了,在这里就不贴图了!

补充:

1、目前,这一秒杀系统的整体构建与代码实战已经全部完成了,完整的源代码数据库地址可以来这里下载:https://gitee.com/steadyjack/SpringBoot-SecondKill 记得Fork跟Star啊!!

2、最后,不要忘记了关注一下Debug的技术微信公众号:

© 著作权归作者所有

稳杰
粉丝 4
博文 18
码字总数 31856
作品 0
广州
高级程序员
私信 提问
加载中

评论(0)

三流程序员与一流程序员之间的区别,看看你是属于哪一类?

源码系列 手写spring mvc框架 基于Spring JDBC手写ORM框架 实现自己的MyBatis Spring AOP实战之源码分析 Spring IOC高级特性应用分析 ORM框架底层实现原理剖析 手写Spring MVC框架实现 手把手...

茶轴的青春
2018/04/17
34
0
Java开发者不会这些永远都只能是三流程序员,细数一下你是不是?

源码系列 手写spring mvc框架 基于Spring JDBC手写ORM框架 实现自己的MyBatis Spring AOP实战之源码分析 Spring IOC高级特性应用分析 ORM框架底层实现原理剖析 手写Spring MVC框架实现 手把手...

美的让人心动
2018/04/16
122
5
阿里面试问题总结(Java工程师)

写在前面 今天是我来杭州找工作后参加的第一次现场面试,也算是工作以来第一次正式的技术面试,超级超级紧张!两个面试官貌似都是做中间件和数据库编程方向的,问的很多我都不太擅长,两轮下...

别打我会飞
2019/03/04
112
0
从程序员到CTO的Java技术路线图

在技术方面无论我们怎么学习,总感觉需要提升自已不知道自己处于什么水平了。但如果有清晰的指示图供参考还是非常不错的,这样我们清楚的知道我们大概处于那个阶段和水平。 Java程序员 高级特...

fighting_zh
2013/06/05
1K
6
如何设计一个web的订票后台服务

hi, all 我在设计一个web订票程序的后台服务。初始的思路如下: 1. 后台发布一个活动,只有10张票,相当于库存。【新建一个Tickets对象放入到缓存。】 2. 多个web打开活动网页,选择购n张票,...

jkluooop
2015/10/15
578
3

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周三乱弹 —— 提高不了工作效率和脸有关系

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @薛定谔的兄弟 :分享洛神有语创建的歌单「我喜欢的音乐」: 1 《夏令时记录(piano.ver)》- ゆめこ 手机党少年们想听歌,请使劲儿戳(这里) ...

小小编辑
今天
67
2
List的一波操作

public static void main(String[] args) { List<Entity> list = new ArrayList<>(); list.add(new Entity(1)); list.add(new Entity(2)); list.add(new Entity(3)); ......

那个猩猩很亮
今天
75
0
Spring基础

主要用于service层; 轻量级java开发框架; 各层 web层:struts,spring-MVC service层:spring dao层:hibernate,mybatis , jdbcTemplate --> spring-data Spring核心:控制反转IOC 切面编...

七宝1
今天
30
0
解决overflow+border-radius+transform圆角问题

网上还有其他版本,但是对我来说都不好使,下面是我在Chrome上的代码。overflow:hidden依然是不能正常使用,换成unset就可以,读者如果有更好的解决方案,请留言,谢谢。 <figure> <img...

hi懒喵
今天
53
0
《C语言》—— 数组

书籍使我变成了一个幸福的人,使我的生活变成轻松而舒适的诗。——高尔基 本文已经收录至我的GitHub,欢迎大家踊跃star 和 issues。 https://github.com/midou-tech/articles 点关注,不迷路!...

龙跃十二
今天
84
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部