关于Spring集成Quartz的一些小坑

1)任务 Job

我们想要调度的任务都必须实现 org.quartz.job 接口,然后实现接口中定义的 execute( ) 方法即可

2)触发器 Trigger

Trigger 作为执行任务的调度器。我们如果想要凌晨1点执行备份数据的任务,那么 Trigger 就会设置凌晨1点执行该任务。其中 Trigger 又分为 SimpleTriggerCronTrigger 两种

3)调度器 Scheduler

Scheduler 为任务的调度器,它会将任务 Job 及触发器 Trigger 整合起来,负责基于 Trigger 设定的时间来执行 Job

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QHjWdY6d-1666531417232)(Quartz.assets/image-20221023160916674.png)]

这是一个Quartz的一个大体架构,由Scheduler作为调度中心,管理Trigger,多个Trigger可以与多个Job进行关联,是一个多对多的关系,Trigger内部分为Simple Trigger和一个Cron Trigger,目前我们用的是后者,使用更便捷,更易于管理

踩的坑

1、Job延迟或不执行

在服务切换第一天,在上线之后用户隐隐有订单反应慢,或者更新不及时的状况,也是没有太注意(粗略观察控制台,看到job有在正常执行),到后面用户反应有的程序已经死掉没有跑了。收到紧急反馈后马上去看了数据库job执行的日志(项目有记录每个job的执行时间、结束时间、耗时),发现有的job确实很久没跑了,或者隔三差五但没有按照预定设置cron的时间进行,第一时间没有定位问题,先把线上控制台日志备份后,马上回滚到旧的定时服务,切换后系统恢复正常。暂时定位确定的是新定时服务内部的问题,隔天上班开始分析备份的备份下来的日志,发现job的执行线程ID,都是在1 ~ 10之间,第一猜想是Job服务数量太多,导致线程不够,job还在排队执行。因为线程ID是在1~10之间,可以猜测Quartz底层使用的是线程池执行任务的,只需要将这个线程池线程数量扩大即可解决,通过查阅并配置后,将配置线程数量调整至50,重新上线测试。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5dRkdaxH-1666531417234)(Quartz.assets/image-20221023160858764.png)]

2、线程池数量配置失效

在最开始发现job延迟或不执行,最后调整线程数量至50。

上线后开始一切正常,执行一段时间后,还是同样的问题,用户反馈任务执行不及时,也是马上下载线上控制台日志后回滚至旧服务,经过观察后线程ID仍然在1~10之间循环,顿时疑惑了,查看Quartz源码后,也是没问题的,照理会去读取这个配置文件没有错,但还是失效了,百度google后仍然百思不得其解,最后在观察代码的时候突然看到了这个Scheduler是使用的@Autowired注解来配置的(Scheduler是任务调度器,线程池也是由Scheduler来使用的,也就是说问题出在这个Scheduler的配置上),猜想会不会是Spring在创建这个Scheduler的时候并没有读取到我的配置或者说被覆盖了,粗略看了Spring装在Scheduler的代码后,发现基于Autowired注解注入的Scheduler是被Spring经过一层封装的,最后在配置文件上加伤Spring的前缀就可以了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cbR7vZD3-1666531417235)(Quartz.assets/image-20221023160838301.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5z6BC3IS-1666531417235)(Quartz.assets/image-20221023211243195.png)]

3、还是服务阻塞

经过上一个坑之后,线程数量的问题完美解决了,但是又出现了一个新的问题,还是有线程被阻塞住没有执行,看了线上控制台日志后,发现线程ID是在正常1 - 100之间循环的,也就证明线程是正常的,但还是会有线程阻塞,第一时间想到的是Http请求超时,连接没有释放,方法也对应着没有结束,而且在调度页面也将这个job改成了异步(不会管他有没有执行完,时间到就执行下一轮),索性就将所有的Http调用加上超时时间,上线后恢复正常运行。

原来的定时服务没有出现这种问题是因为,之前用的Hutool的一个cron工具包进行调度,底层没有用线程池化技术,也就是差不多每个线程都是new Thread().start()执行,由于Quartz使用的是线程池,就会有线程阻塞的问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值