数据库中建表。建表模版在Quartz包下docs/dbTables下,选择相应的数据库和版本即可。ORACLE的11个Table列表如下:
QRTZ_JOB_LISTENERS:存储有关已配置的 JobListener 的信息
JOB_NAME
JOB_GROUP
JOB_LISTENER
QRTZ_TRIGGER_LISTENERS:存储已配置的 TriggerListener 的信息
QRTZ_FIRED_TRIGGERS:存储与已触发的 Trigger 相关的状态信息,以及相联 Job的执行信息
QRTZ_PAUSED_TRIGGER_GRPS:存储已暂停的 Trigger 组的信息
QRTZ_SCHEDULER_STATE:存储集群中note实例信息,quartz会定时读取该表的信息判断集群中每个实例的当前状态
INSTANCE_NAME 之前配置文件中orgquartzschedulerinstanceId配置的名字,就会写入该字段,如果设置为AUTO,quartz会根据物理机名和当前时间产生一个名字
LAST_CHECKIN_TIME:上次检查时间
CHECKIN_INTERVAL :检查间隔时间
QRTZ_LOCKS:存储程序的悲观锁的信息(假如使用了悲观锁)
QRTZ_SIMPLE_TRIGGERS:存储简单的Trigger,包括重复次数,间隔,以及已触的次数
TRIGGER_NAME :qrtz_triggers表trigger_name的外键
TRIGGER_GROUP:qrtz_triggers表trigger_group的外键
REPEAT_COUNT :重复次数
REPEAT_INTERVAL:时间间隔
TIMES_TRIGGERED:触发次数
QRTZ_CRON_TRIGGERS:存储cron表达式表
TRIGGER_NAME :qrtz_triggers表trigger_name的外键
TRIGGER_GROUP:qrtz_triggers表trigger_group的外键
CRON_EXPRESSION:cron表达式
TIME_ZONE_ID :时区
QRTZ_TRIGGERS:保存trigger信息
crond是Linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,在CentOS Linux release 721511中默认是开机启动的,大家可以使用命令:systemctl status crond进行查看。 crond进程定期(每分钟)检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。用户在cron表
(也被称为crontab文件)指定了定时任务,crontab也就是我们常见的定时任务设置命令。Linux下的任务调度分为两类,系统任务调度和用户任务调度。
系统任务调度 :系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。/etc/crontab文件就是系统任务调度的配置文件。
用户任务调度 :用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。用户可以使用 crontab 工具来定制自己的计划任务。所有用户定义的crontab文件都被保存在/var/spool/cron目录中。其文件名与用户名一致,使用者权限文件如下:
通过以上帮助信息,我们可以知道crond是执行任务计划的一个守护进程。在使用crontab之前我们可以根据帮助信息来设置相关选项,一般情况下我们都使用默认值。
1建立演示账号crontab。
2星号()使用举例。
以上例子中完整演示了crontab从建立到执行的过程。“5 0 echo "GeekDevOps"”表示在每天00:05执行命令:echo "GeekDevOps"。后面的星号表示只要前面条件满足都执行。例子中的-u选项指定了用户:crontab,-l选项列举了相关用户的用户任务调度,不指定用户则默认为root。执行结果默认写入到用户mail目录下的相关文件中。
3逗号(,)的使用举例。
现在我们已经把用户切换到crontab下,因此无需额外指定-u选项相关内容。“3 2,6,8 ”表示每天的02:03:00、06:03:00、08:03:00分别执行一次命令:ls /usr/local。
4减号(-)的使用举例。
例子中的“0 2-6 6 df -h /”表示用户crontab在每周六的02:00、03:00、04:00、05:00、06:00执行命令:df -h / 。
5斜杠(/)的使用举例。
例子中表示每隔2分钟执行一次命令:echo "GeekDevOps">>/root/GeekDevOpstxt。
6crontab的使用非常简单,很容易理解,只要在取值范围内设置执行的值基本是没有问题的。现在我们要删除已经设置的这些定时任务。
例子中,选项-r表示删除所有定时任务。选项-i表示在删除前进行再次确定,输入y或者Y才能真正删除。
7备份我们设置的用户任务调度配置文件。
8系统任务调度的使用举例。
系统任务调度与用户任务调度不一样,需要直接在/etc/crontab里面配置,如果需要指定用户,还需要在执行命令前指定用户名。通过crontab -l 命令是查看不到系统任务调度任务的。
什么是动态定时任务:是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定)。
这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户修改配置文件,但总需要重新启动web服务啊,研究了下Quartz在Spring中的动态定时,发现<bean id="cronTrigger" class="orgspringframeworkschedulingquartzCronTriggerBean" >
<property name="jobDetail" ref="schedulerJobDetail"/>
<property name="cronExpression">
<value>0/10 </value>
</property>
中cronExpression是关键,如果可以动态设置cronExpression的值,也就说如果我们可以直接调用CronTriggerBean中设置cronExpression的方法,就可以顺利解决问题了。
熟悉1的朋友可以跳过不看,下面2、3是动态定时任务的具体实现。
1. Quartz在Spring中的简单配置
Spring配置文件:
<bean id="schedulerJobDetail" class="orgspringframeworkschedulingquartzMethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="scheduleInfoAction"/>
<property name="targetMethod" value="simpleJobTest"/>
<property name="concurrent" value="false"/>
</bean>
<bean id="cronTrigger" class="orgspringframeworkschedulingquartzCronTriggerBean" >
<property name="jobDetail" ref="schedulerJobDetail"/>
<property name="cronExpression">
<value>0/10 </value>
</property>
</bean>
<bean id="schedulerFactory" class="orgspringframeworkschedulingquartzSchedulerFactoryBean">
<property name="triggers">
<list>
<ref local="cronTrigger"/>
</list>
</property>
</bean>
在上面的配置中设定了
① targetMethod: 指定需要定时执行scheduleInfoAction中的simpleJobTest()方法
② concurrent:对于相同的JobDetail,当指定多个Trigger时, 很可能第一个job完成之前,第二个job就开始了。指定concurrent设为false,多个job不会并发运行,第二个job将不会在第一个job完成之前开始。
③ cronExpression:0/10 表示每10秒执行一次,具体可参考附表。
④ triggers:通过再添加其他的ref元素可在list中放置多个触发器。
scheduleInfoAction中的simpleJobTest()方法
注意:此方法没有参数,如果scheduleInfoAction有两个方法simpleJobTest()和simpleJobTest(String argument),则spring只会去执行无参的simpleJobTest()
public void simpleJobTest() {
logwarn("uh oh, Job is scheduled !'" + "' Success");
}
2.Quartz在Spring中动态设置cronTrigger方法一
Spring配置文件:
<bean id="scheduleInfoAction" class="comlivelyhappyoajobswebappactionScheduleInfoAction">
<property name="scheduler" ref="schedulerFactory"/>
<property name="scheduleInfoManager" ref="scheduleInfoManager"/>
</bean>
<bean id="schedulerJobDetail" class="orgspringframeworkschedulingquartzMethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="scheduleInfoAction"/>
<property name="targetMethod" value="reScheduleJob"/>
<property name="concurrent" value="false"/>
</bean>
<bean id="cronTrigger" class="orgspringframeworkschedulingquartzCronTriggerBean" >
<property name="jobDetail" ref="schedulerJobDetail"/>
<property name="cronExpression">
<value>0/10 </value>
</property>
</bean>
<bean id="schedulerFactory" class="orgspringframeworkschedulingquartzSchedulerFactoryBean">
<property name="triggers">
<list>
<ref local="cronTrigger"/>
</list>
</property>
</bean>
scheduleInfoAction中的reScheduleJob ()方法及相关方法
① reScheduleJob读取数据库,获得自定义定时器调度时间():
private void reScheduleJob() throws SchedulerException, ParseException {
// 运行时可通过动态注入的scheduler得到trigger
CronTriggerBean trigger = (CronTriggerBean) schedulergetTrigger(
"cronTrigger", SchedulerDEFAULT_GROUP);
String dbCronExpression = getCronExpressionFromDB();
String originConExpression = triggergetCronExpression();
// 判断从DB中取得的任务时间(dbCronExpression)和现在的quartz线程中的任务时间(originConExpression)是否相等
// 如果相等,则表示用户并没有重新设定数据库中的任务时间,这种情况不需要重新rescheduleJob
if(!originConExpressionequalsIgnoreCase(dbCronExpression)){
triggersetCronExpression(dbCronExpression);
schedulerrescheduleJob("cronTrigger", SchedulerDEFAULT_GROUP, trigger);
}
// 下面是具体的job内容,可自行设置
// executeJobDetail();
}
② getCronExpressionFromDB():从数据库中获得dbCronExpression的具体代码,由于使用了scheduleInfoManager,所以要在定义相应的setter方法
private String getCronExpressionFromDB(){
String sql="from ScheduleInfo scheduleInfo where 1=1 ";
sql=sql+" and scheduleInfoinfoId = '"+"1" + "'";
List scheduleList = scheduleInfoManagerqueryScheduleInListBySql(sql);
ScheduleInfo scheduleInfo = (ScheduleInfo)scheduleListget(0);
String dbCronExpression = scheduleInfogetCronExpression();
return dbCronExpression;
}
③ 在spring配置文件的scheduleInfoAction配置了相应的property(scheduler/ scheduleInfoManager),要为其设置setter方法
private Scheduler scheduler;
// 设值注入,通过setter方法传入被调用者的实例scheduler
public void setScheduler(Scheduler scheduler) {
thisscheduler = scheduler;
}
private ScheduleInfoManager scheduleInfoManager;
// 设值注入,通过setter方法传入被调用者的实例scheduleInfoManager
public void setScheduleInfoManager(ScheduleInfoManager scheduleInfoManager){
thisscheduleInfoManager = scheduleInfoManager;
}
3. Quartz在Spring中动态设置cronTrigger方法二
在上面的2中我们可以看到,尽管已经可以动态进行rescheduleJob了,不过依然需要我们设置一个cronExpression,如果尝试一下拿掉spring配置中的
<property name="cronExpression">
<value>0/10 </value>
</property>
则容器(如tomcat)启动时会报错。
实际中我们希望tomcat启动时就可以直接去读数据库,拿到相应的dbCronExpression,然后定时执行一个job,而不希望配置初始的cronExpression ,观察下面的CronTriggerBean,考虑到cronExpression需要初始化,如果设定一个类InitializingCronTrigger继承CronTriggerBean,然后在这个类中做一些读取DB的初始化工作(设置cronExpression),问题就可以解决了。
Spring配置文件:
<bean id="scheduleInfoAction" class="comlivelyhappyoajobswebappactionScheduleInfoAction">
<property name="scheduler" ref="schedulerFactory"/>
<property name="scheduleInfoManager" ref="scheduleInfoManager"/>
</bean>
<bean id="schedulerJobDetail" class="orgspringframeworkschedulingquartzMethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="scheduleInfoAction"/>
<property name="targetMethod" value="reScheduleJob"/>
<property name="concurrent" value="false"/>
</bean>
<bean id="cronTrigger" class="comlivelyhappyoajobswebappactionScheduleInfoActionInitializingCronTrigger">
<property name="jobDetail" ref="schedulerJobDetail"/>
<!--<property name="cronExpression">
<value>0/10 </value>
</property>-->
<property name="scheduleInfoManager" ref="scheduleInfoManager"/>
</bean>
<bean id="schedulerFactory" class="orgspringframeworkschedulingquartzSchedulerFactoryBean">
<property name="triggers">
<list>
<ref local="cronTrigger"/>
</list>
</property>
</bean>
InitializingCronTrigger中的相关方法
注意:在注入scheduleInfoManager属性的时候,我们可以去读取DB任务时间(之所以放在setter方法中,是因为需要在设置scheduleInfoManager后进行getCronExpressionFromDB(),否则,也可以①②逻辑把放在类的构造函数中)
注意InitializingCronTrigger必须extends CronTriggerBean
public class InitializingCronTrigger extends CronTriggerBean implements Serializable {
private ScheduleInfoManager scheduleInfoManager;
// 设值注入,通过setter方法传入被调用者的实例scheduleInfoManager
public void setScheduleInfoManager(ScheduleInfoManager scheduleInfoManager){
thisscheduleInfoManager = scheduleInfoManager;
// 因为在getCronExpressionFromDB使用到了scheduleInfoManager,所以
// 必须上一行代码设置scheduleInfoManager后进行getCronExpressionFromDB
String cronExpression = getCronExpressionFromDB (); // ①
// 因为extends CronTriggerBean ,此处调用父类方法初始化cronExpression
setCronExpression(cronExpression); // ②
}
private String getCronExpressionFromDB(){
String sql="from ScheduleInfo scheduleInfo where 1=1 ";
sql=sql+" and scheduleInfoinfoId = '"+"1" + "'";
List scheduleList = scheduleInfoManagerqueryScheduleInListBySql(sql);
ScheduleInfo scheduleInfo = (ScheduleInfo)scheduleListget(0);
String dbCronExpression = scheduleInfogetCronExpression();
return dbCronExpression;
}
……
}
附表:
"0 0 12 " 每天中午12点触发
"0 15 10 " 每天上午10:15触发
"0 15 10 " 每天上午10:15触发
"0 15 10 " 每天上午10:15触发
"0 15 10 2005" 2005年的每天上午10:15触发
"0 14 " 在每天下午2点到下午2:59期间的每1分钟触发
"0 0/5 14 " 在每天下午2点到下午2:55期间的每5分钟触发
"0 0/5 14,18 " 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
"0 0-5 14 " 在每天下午2点到下午2:05期间的每1分钟触发
"0 10,44 14 3 WED" 每年三月的星期三的下午2:10和2:44触发
"0 15 10 MON-FRI" 周一至周五的上午10:15触发
"0 15 10 15 " 每月15日上午10:15触发
"0 15 10 L " 每月最后一日的上午10:15触发
"0 15 10 6L" 每月的最后一个星期五上午10:15触发
"0 15 10 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发
"0 15 10 6#3" 每月的第三个星期五上午10:15触发
每隔5秒执行一次:/5
每隔1分钟执行一次:0 /1
每天23点执行一次:0 0 23
每天凌晨1点执行一次:0 0 1
每月1号凌晨1点执行一次:0 0 1 1
每月最后一天23点执行一次:0 0 23 L
每周星期天凌晨1点实行一次:0 0 1 L
至于每个符号 看看例子就好了很简单了
以上就是关于如何在quartz的job任务中 *** 作数据库全部的内容,包括:如何在quartz的job任务中 *** 作数据库、Linux下定时任务(系统任务调度、用户任务调度)crontab使用详解、spring cron配置每几分钟怎么设置等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)