DIAODU

xxx

---系统调度机制与开发入手介绍

 

日期

描述 

版本

作者


文档创建与内容编写

V1.0


 

 

 

 

 

调度机制Quartz介绍

本文只对Quartz做简单介绍。Quartz是一个开源的框架,相关的网络资料资源丰富,需要详细了解可自行去查找查看。

使用Quartz框架开发简单的调度任务,只需关注调度器、任务和触发器这3个核心的概念。它们分别是任务JobDetail、触发器Trigger、调度器Scheduler;了解三者之间关系即可实施开发。

●Job:是一个接口,只有一个方法voidexecute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息。Job运行时的信息保存在JobDataMap实例中;

 

●JobDetail:Quartz在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接收一个Job实现类,以便运行时通过newInstance()的反射机制实例化Job。因此需要通过一个类来描述Job的实现类及其它相关的静态信息,如Job名字、描述、关联监听器等信息,JobDetail承担了这一角色。

●Trigger:是一个类,描述触发Job执行的时间触发规则。主要有SimpleTrigger和CronTrigger这两个子类。当仅需触发一次或者以固定时间间隔周期执行,SimpleTrigger是最适合的选择;而CronTrigger则可以通过Cron表达式定义出各种复杂时间规则的调度方案:如每早晨9:00执行,周一、周三、周五下午5:00执行等;

 

●Calendar:org.quartz.Calendar和java.util.Calendar不同,它是一些日历特定时间点的集合(可以简单地将org.quartz.Calendar看作java.util.Calendar的集合——java.util.Calendar代表一个日历时间点,无特殊说明后面的Calendar即指org.quartz.Calendar)。一个Trigger可以和多个Calendar关联,以便排除或包含某些时间点。

●Scheduler:代表一个Quartz的独立运行容器,Trigger和JobDetail可以注册到Scheduler中,两者在Scheduler中拥有各自的组及名称,组及名称是Scheduler查找定位容器中某一对象的依据,Trigger的组及名称必须唯一,JobDetail的组和名称也必须唯一(但可以和Trigger的组和名称相同,因为它们是不同类型的)。Scheduler定义了多个接口方法,允许外部通过组及名称访问和控制容器中Trigger和JobDetail。

 

Scheduler可以将Trigger绑定到某一JobDetail中,这样当Trigger触发时,对应的Job就被执行。一个Job可以对应多个Trigger,但一个Trigger只能对应一个Job。可以通过SchedulerFactory创建一个Scheduler实例。Scheduler拥有一个SchedulerContext,它类似于ServletContext,保存着Scheduler上下文信息,Job和Trigger都可以访问SchedulerContext内的信息。SchedulerContext内部通过一个Map,以键值对的方式维护这些上下文数据,SchedulerContext为保存和获取数据提供了多个put()和getXxx()的方法。可以通过Scheduler# getContext()获取对应的SchedulerContext实例;

 

●ThreadPool:Scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率。

集成Quartz

本文Quartz介绍说明了调度器、任务和触发器的关系,调度器负责将任务和触发器进行绑定。在Spring集成中,只需在配置文件中将它们关系绑定即可。

驾驶舱中使用的MVC框架为Spring,而在Spring中使用Quartz有两种方式实现:

第一种是任务类继承QuartzJobBean;

第二种则是在配置文件里定义任务类和要执行的方法,类和方法仍然是普通JavaBean类。

 

由于驾驶舱采取集群部署,调度需要解决集群的问题,Quartz具备任务持久化功能,且可以解决集群调度问题。持久化任务的Java类(含其属性类)必须是实现序列化接口Serializable类,否则将抛出持久化异常。第二种集成方式虽然更好解耦代码,但可能会容易增加后期增加其它调度的问题,因此排除使用,而选择使用第一种方式集成,即继承任务类QuartzJobBean。

要使Quartz任务其作用,需要进行配置,一般在xml中要有配置JobDetail、Trigger、Scheduler三个Bean配置。由于持久化需要,以上三个Bean配置建议使用JobDetailFactoryBean、CronTriggerFactoryBean、SchedulerFactoryBean等*FactoryBean,以免持久化或其它集成问题出现。

以下为第一种方式配置样例(详见quartz-config.xml文件):

<!-- 主数据账户同步调度(调用SSO提供的主数据接口来实施同步)-->

        <bean name="synAccountFromMainDataJob"class="org.springframework.scheduling.quartz.JobDetailFactoryBean">

            <!-- 表示任务完成之后是否依然保留到数据库,默认false -->

            <propertyname="durability" value="true" />

            <property name="jobClass"value="com.cmb.app.driverhome.sso.quartz.SynAccountFromMainDataJobTask"/>

        </bean>

       

        <!-- 主数据账户同步调度(调用SSO提供的主数据接口来实施同步)每天凌晨4点(0 0 4 * * ?) 执行-->

        <bean id="synAccountFromMainDataTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">

            <propertyname="jobDetail">

                <ref bean="synAccountFromMainDataJob"/>

            </property>

            <propertyname="cronExpression" value="0 0/5 * * * ?" />

        </bean>

<beanid="sysGlobalScheduler" lazy-init="false"autowire="no"class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

            <propertyname="triggers">

                <list>

                    <!-- 在此注释,则不作调度处理-->

                    <ref bean="synAccountFromMainDataTrigger"/>                

                </list>

            </property>

            <propertyname="applicationContextSchedulerContextKey"value="applicationContext" />

            <propertyname="dataSource">

               <refbean="dataSource" />

            </property>

            <propertyname="transactionManager">

                <refbean="transactionManager" />

            </property>

            <propertyname="configLocation" value="classpath:quartz.properties"/>      

        </bean>

由于任务持久化需要,配置必须要有DB连接。在样例中,SchedulerFactoryBean 的dataSource 配置了连接,而configLocation属性指定quartz.properties配置文件必须为集群配置:

org.quartz.jobStore.misfireThreshold = 60000

#JDBC持久化到DB的配置

org.quartz.jobStore.class =org.quartz.impl.jdbcjobstore.JobStoreTX

org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate

org.quartz.jobStore.tablePrefix = QRTZ_

org.quartz.jobStore.maxMisfiresToHandleAtATime=10

org.quartz.jobStore.isClustered= true 

org.quartz.jobStore.clusterCheckinInterval = 20000

 

 

系统调度开发入手

驾驶舱定义调度任务的基类:com.cmb.app.driverhome.common.quartz. BaseScheduleTask,其继承org.springframework.scheduling.quartz.QuartzJobBean,主要为提供开发继承使用。

驾驶舱系统中开发任何的调度任务,只需继承BaseScheduleTask并重写executeInternal方法,然后在quartz-config.xml文件按集成方式说明进行配置,可参照已有任务进行配置即可实现任务调度功能。

   【需要特别说明】:

    配置的调度任务在工程首次启动后即被持久化到DB表(qrtz_开头的表),再次启动的时候,工程会直接读取DB表的任务去进行调度;因此对xml中trigger的表达式配置的修改可能不会其作用。解决方法为采取的方式是手工在DB表(qrtz_cron_triggers和qrtz_triggers)中修改,或将它们从DB表(qrtz_cron_triggers和qrtz_triggers)中删除,工程重启时会再自动持久化添加调度任务到DB表。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值