基于Quartz的可自定义作业调度系统的设计与实现

2019-05-07 02:04沈宇杰
通化师范学院学报 2019年4期
关键词:线程引擎调度

沈宇杰

1 背景简介

在现代的企事业单位,越来越多地涉及到作业调度系统.例如金融、保险、网站和计算机管理系统等主流的工作场景,都需要合理的调度,对于访问量和工作量巨大的电商类任务场景,利用Quartz框架可以很好地帮助企业实现常规和复杂的作业调度功能[1].Quartz是开源组织“Open-Symphony”的一个项目[2],它完全基于Java实现,具有强大的调度功能[3].本文以Quartz为核心,提出了一种改进型系统.与基本的Quartz系统相比,改进型系统增添了“精确调度”“自定义任务”等新功能,增强了Quartz的功能.

2 系统的整体架构

关于作业调度,有些开发者在遇到此类问题时,一般会考虑使用Web Services实现[4].而本系统则利用Quartz的基本框架,添加了新的功能逻辑.为确保可伸缩性,采用了基于多线程的架构[5].本系统主要分为调度引擎和自定义任务引擎两个部分.

①调度引擎,主要负责任务的精确设定与触发.

②自定义任务引擎,主要负责两项工作,即标准化自定义任务接口和任务执行系统初始化时,调度引擎服务启动Quartz服务,分别在计算机内存和数据库中注册调度信息.当一个调度信息被Quartz服务触发后,其包含的任务信息被写入数据库.随后,自定义任务引擎则轮询数据库中的这些任务信息,将符合条件的任务放入线程池中运行.

改进型系统与基本Quartz系统比较的差异见图1.

图1 本系统与基本Quartz系统的比较

3 系统数据库设计

本系统的数据库主要使用的表如下.

①Schedule表:存放作业调度信息,Quartz基本框架将使用该表.

②Configuration表:存放配置信息,调度引擎将使用该表.

③Job表:存放要进入线程池的自定义任务,自定义任务引擎将使用该表.

④TimeTrigger表:作业调度的触发信息,Quartz基本框架将使用该表.

⑤JobDefinition表:自定义作业的具体细节,自定义任务引擎将使用该表.

⑥Joblog表:存放作业日志信息,自定义任务引擎将使用该表.

上述各数据表中,Configuration表具有独立性,其他各数据表之间的逻辑关系如图2所示.

图2 系统的数据表逻辑关系

4 自定义任务的接口方法设计

本系统要实现自定义任务的运行,必须为任务设定通用的接口模式,当添加自定义任务时,主要有以下6个接口方法需要实现.

①execute():该方法执行任务的具体业务逻辑,是核心方法.当自定义任务的实例任务引擎执行时,该方法被调用.

②pause():暂停任务的运行.如果暂停成功,结果返回true,结果失败返回false.

③resume():恢复任务的运行.它与pause方法相反,先暂停后才能恢复.恢复成功返回结果true,如果失败则返回结果false.

④stop():终止任务的运行,成功则返回true,失败则返回false.若该作业不支持停止操作,则直接返回false.

⑤onQueue():任务在进入执行线程池前,需要调用的方法.用于执行前的准备工作.

⑥onComplete():任务执行完毕后的结束动作,在execute方法执行完毕后被调用.比如任务完成后,需要将生成的结果,通过E-mail发给相关的人员.发E-mail这个动作就可以在onComplete方法中实现.

5 调度引擎模块的设计

5.1 Quartz的基本接口

当系统导入Quartz插件包后,需要继承Quartz的接口,才能使用其功能.在Quartz中,有以下几个基本的类.

(1)Schdeuler类:这个类的方法将调度信息写入系统内存,使Quartz在设定的时间触发调度.

(2)Job接口:用户自定义任务的统一接口.开发人员将自定义逻辑写入Job接口的execute方法中,一旦任务触发,Job类的execute方法将会被调用,执行写入的自定义逻辑.

(3)JobExecuteContext类:此类是 Scheudler类与Job类通讯的上下文参数.

(4)JobDetail类:自定义任务的具体参数,被Schedule.scheduleJob(JobDetail,Trigger)方 法 所使用.

(5)Trigger类:此类是Quartz的核心类,用于设置开始时间、结束时间、执行次数等等,并可以设置两种触发类型,分别是Corn表达式型和Intval型.

①Cron表达式方式.Cron表达式是Quartz特有的字符串,当Quartz读取到该类字符串时,会自动解析出该表达式的含义,从而实现用户期望的调度信息,表达式分为七段,分别表示秒,分,时,日,月,周,年.示例见表1.

表1 具体示例

②Inteval方式.Inteval方式与Cron表达式不同,它以精确的间隔来触发任务,即每次触发的间隔是恒定不变的.Quartz中间隔的单位一般是秒,分,时,最大不会大于小时.

在Quartz的架构中,新任务必须先实现Job类的接口,将业务逻辑代码写入execute方法,并设置任务的具体参数(JobDetail类)和调度信息(Trigger类).随后系统调用Schdeule类的Schedule.scheduleJob(JobDetail,Trigger)方法,将新任务写入系统进程.当调度信息被触发时,任务引擎通过Schdeule类解析出jobDetail类中包含的作业参数,传递给新任务实例,用于execute方法的执行.

5.2 调度引擎模块设计

这个模块主要实现2部分功能,一是将任务信息注册到Quartz实时服务中;二是实现已注册任务信息的持久化.

(1)持久化.计算机一旦出现重启或者服务中断,必须将Quartz实时服务中的任务信息写入数据库,否则系统因为各种原因重启时,就会失去所有任务的状态,导致调度的混乱.持久化的构建方法是使用Schedule表和Trigger表存储现场信息.Schedule表是用于存储调度信息的,包含自定义任务的类型、调度的类型、调度的状态、触发器的信息、任务执行信息等等.trigger表存储每个调度信息的具体调度计划,例如触发时间、已触发次数、剩余触发次数等等.

(2)新的调度信息创建时,系统会将任务信息、触发时间、触发次数等具体参数进行封装,传递给调度引擎.调度引擎根据封装内容,把相应的调度信息插入Schedule表和Trigger表,并通过ID关联两者.这样一个任务的调度信息就被写入数据库,完成了持久化的第一步.第二步,调度引擎将调度信息注册到Quartz实时服务,Quartz实时服务就开始掌管这条新的调度信息了.

核心代码如下:

当触发时刻到来时,Quartz实时服务将启动一个调度,读取任务的类型,将自定义任务插入Job表中,供随后的自定义任务引擎轮询筛选.插入操作完成后,修改Schedule表与Trigger表中的触发状态信息,使之与内存中调度信息一致(见图3).

图3 调度信息的设置

在这期间,如果发生服务器重启,Quartz实时服务中的调度信息都会丢失.所以在服务器重启时,调度引擎会根据Schedule表与Trigger表还原现场,将所有未完成的调度信息重新插入内存,这样调度系统可以继续工作了.

为了避免服务重启时,大量丢失的任务同时触发,导致资源耗尽,调度引擎服务需要设置自己的规则,当同一个调度丢失多个周期的调度触发,在重启还原时只触发一次(见图4).

图4 系统重启时还原现场

6 自定义任务引擎模块的设计

(3)线程池将这条新的作业加入线程队列.

(4)作业开始被线程池执行.

(5)作业运行完毕,自定义任务引擎修改作业的状态,最终成为“完成”或者“失败”.

图5 自定义任务引擎模块的工作流程

6.1 线程池技术的引入

本模块使用了多线程技术,以此来实现并发处理任务.该技术主要解决多个线程同时需要执行的问题,显著减少处理环节的闲置时间,增加处理器吞吐的能力,很好地实现多任务并发.在本系统中,自定义任务引擎是执行任务的模块,所以主要使用线程池技术来实现并发执行.本系统线程池的实现是通过使用Java提供的java.util.concurrent工具包来实现的.

6.2 具体实现流程

调度引擎启动一个任务时,将任务信息插入数据库中的Job表,而自定义任务引擎每4秒轮询这张Job表.当Job表中的任务信息符合条件时,就会进入线程池按照顺序执行.

任务运行时的关键点,是提供自定义作业的运行参数,自定义任务引擎会读取任务记录里的Schedule Id字段去关联Schedule表中相应调度信息,读取记录中的ParamterContext内容,作为任务运行的参数.运行的流程见图5.

(1)调度引擎模块将符合调度触发的自定义任务写入Job表.

(2)自定义任务引擎每4秒轮询这张Job表,当有新记录加入时,这条记录被放入线程池.

7 总结

本系统在Quartz基本框架的基础上,设计并实现了一个可自定义作业的调度系统,该系统能够应用于大多数的作业调度场合,采用了并发技术和线程池,能够有效应对系统的掉电与重启,并能够根据用户的需要,添加自定义的任务作业.本系统的设计思路可以应用于其他作业调度的应用场景,具有一定的参考价值.

猜你喜欢
线程引擎调度
基于C#线程实验探究
新海珠,新引擎,新活力!
车坛往事4:引擎进化之屡次失败的蒸汽机车
《调度集中系统(CTC)/列车调度指挥系统(TDCS)维护手册》正式出版
基于国产化环境的线程池模型研究与实现
电力调度自动化中UPS电源的应用探讨
基于强化学习的时间触发通信调度方法
线程池调度对服务器性能影响的研究*
基于动态窗口的虚拟信道通用调度算法
蓝谷: “涉蓝”新引擎