`
sillycat
  • 浏览: 2551982 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

定时任务管理(一)quartz了解

    博客分类:
  • JAVA
阅读更多
定时任务管理(一)quartz了解

最近公司需要做个quartz定时任务管理的单独项目,需求是可以调度本省项目中的groovy文件操作数据库来统计出数据放置到XML等文件中;或者调用其他业务模块的jar包里面的业务manager方法去查询,得到结果存放到XML等文件中。

quartz首页
http://www.quartz-scheduler.org/
详细文档
file:///E:/book/opensource/quartz/quartz-1.6.6/docs/wikidocs/index.html

我参考了如下文章:
容器启动时就装在用户定的时间设置
http://blog.csdn.net/vvggsky/archive/2007/03/01/1517744.aspx
实现了动态设定任务时间
(一)http://allen-zhe.iteye.com/blog/48305
(二)http://allen-zhe.iteye.com/blog/48304
(三)http://allen-zhe.iteye.com/blog/48303
实现了动态任务设置
http://devbbs.doit.com.cn/thread-10948-1-1.html

按照这些文章上的,部署了实例,并开始查看代码和数据库
添加一个Job在表qrtz_job_details插入一条记录
添加一个Simple Trigger在表qrtz_simple_triggers插入一条记录
添加一个Cron Trigger 在表qrtz_cron_triggers插入一条记录
添加Simple Trigger和Cron Trigger都会同进在表qrtz_triggers插入一条记录,开始看的第一个页面调度任务列表数据就是从qrtz_triggers表获取的

在参考别人BLOG的基础上,我想让JOB也得到管理,所以我在DAO上增加了一个方法,当然,也没有修改应用使用IBATIS实现,还是使用的它原有的template,QuartzDAOImpl.java如下,其中的两条SQL是核心,是我查询jobs和triggers时使用的:
@SuppressWarnings("unchecked")
//返回所有的任务
public List<Map<String, Object>> getOrtzJobs() {
List<Map<String, Object>> results = getJdbcTemplate().queryForList(
    "select * from QRTZ_JOB_DETAILS");
String temp = null;
for (Map<String, Object> map : results) {
   temp = MapUtils.getString(map, "job_name");
   map.put("display_name", StringUtil.getOrgName(temp));
}
return results;
}
@SuppressWarnings("unchecked")
// 返回所有triggers
public List<Map<String, Object>> getQrtzTriggers() {
List<Map<String, Object>> results = getJdbcTemplate().queryForList(
    "select * from QRTZ_TRIGGERS order by start_time");
long val = 0;
String temp = null;
for (Map<String, Object> map : results) {
   temp = MapUtils.getString(map, "trigger_name");
   map.put("display_name", StringUtil.getOrgName(temp));
   temp = MapUtils.getString(map, "job_name");
   map.put("display_job_name", StringUtil.getOrgName(temp)); 
   val = MapUtils.getLongValue(map, "next_fire_time");
   if (val > 0) {
    map.put("next_fire_time", DateFormatUtils.format(val,
      "yyyy-MM-dd HH:mm:ss"));
   }
   val = MapUtils.getLongValue(map, "prev_fire_time");
   if (val > 0) {
    map.put("prev_fire_time", DateFormatUtils.format(val,
      "yyyy-MM-dd HH:mm:ss"));
   }
   val = MapUtils.getLongValue(map, "start_time");
   if (val > 0) {
    map.put("start_time", DateFormatUtils.format(val,
      "yyyy-MM-dd HH:mm:ss"));
   }
   val = MapUtils.getLongValue(map, "end_time");
   if (val > 0) {
    map.put("end_time", DateFormatUtils.format(val,
      "yyyy-MM-dd HH:mm:ss"));
   }
   map.put("status", Constant.status.get(MapUtils.getString(map,
     "trigger_state")));
}
return results;
}
在原有SchedulerService的基础上,增加了对job的管理的方法,SchedulerServiceImpl.java如下:
// 新增job
public void addJob(String jobName, String groupName, String jobClassName,
   Map<String, Object> paras) {
jobName = StringUtil.getUUIDName(jobName);
if (StringUtil.isBlank(groupName)) {
   groupName = Scheduler.DEFAULT_GROUP;
}
if (StringUtil.isBlank(jobClassName)) {
   log.error("jobClassName can't be null!");
   throw new RuntimeException("jobClassName can't be null!");
}
Job jobClass = null;
try {
   jobClass = (Job) Class.forName(jobClassName).newInstance();
} catch (ClassNotFoundException e) {
   log.error(e.getMessage());
   throw new RuntimeException(e);
} catch (InstantiationException e) {
   log.error(e.getMessage());
   throw new RuntimeException(e);
} catch (IllegalAccessException e) {
   log.error(e.getMessage());
   throw new RuntimeException(e);
}
JobDetail jobDetail = null;
jobDetail = new JobDetail(jobName, groupName, jobClass.getClass());
if (paras != null && paras.isEmpty()) {
   jobDetail.getJobDataMap().putAll(paras);
}
try {
   scheduler.addJob(jobDetail, true);
} catch (SchedulerException e) {
   log.error(e.getMessage());
   throw new RuntimeException(e);
}
}
// 新增spring job,paras里面是关联bean,用“,”分隔
public void addSpringJob(String jobName, String groupName,
   String springBeanName, Map<String, Object> paras) {
jobName = StringUtil.getUUIDName(jobName);
if (StringUtil.isBlank(groupName)) {
   groupName = Scheduler.DEFAULT_GROUP;
}
if (StringUtil.isBlank(springBeanName)) {
   log.error("springBeanName can't be null!");
   throw new RuntimeException("springBeanName can't be null!");
}
Job job = null;
ApplicationContext cxt = getApplicationContext();
if (cxt == null) {
   log.error("spring context is null!");
   throw new RuntimeException("spring context is null!");
}
Object jobDetail_obj = cxt.getBean(springBeanName);
if (jobDetail_obj == null) {
   log.error("context has not bean named: " + springBeanName);
   throw new RuntimeException("context has not bean named: "
     + springBeanName);
}
job = (Job) jobDetail_obj;
JobDetail jobDetail = null;
jobDetail = new JobDetailBean();
jobDetail.setName(jobName);
jobDetail.setGroup(groupName);
jobDetail.setJobClass(job.getClass());
if (paras != null && !paras.isEmpty()) {
   JobDataMap jobDataMap = new JobDataMap();
   jobDataMap.putAll(paras);
   Object relateBeans_obj = paras.get("RELATE_BEANS");
   if (relateBeans_obj != null) {
    String relateBeans_str = (String) relateBeans_obj;
    if (StringUtil.isNotBlank(relateBeans_str)) {
     String[] relateBeans = relateBeans_str.split(",");
     if (relateBeans != null && relateBeans.length > 0) {
      for (int i = 0; i < relateBeans.length; i++) {
       String relateBean = relateBeans[i];
       jobDataMap.put(relateBean, cxt.getBean(relateBean));
      }
     }
    }
   }
   jobDetail.setJobDataMap(jobDataMap);
}
try {
   scheduler.addJob(jobDetail, true);
} catch (SchedulerException e) {
   log.error(e.getMessage());
   throw new RuntimeException(e);
}
}
// 新增触发器
public void addTrigger(String triggerName, String cronExpression,
   String groupName, String jobName) {
CronExpression cron = null;
try {
   cron = new CronExpression(cronExpression);
} catch (ParseException e) {
   log.error(e.getMessage());
   throw new RuntimeException(e);
}
addTrigger(triggerName, cron, groupName, jobName);
}
// 触发器真实新增方法
private void addTrigger(String triggerName, CronExpression cronExpression,
   String groupName, String jobName) {
triggerName = StringUtil.getUUIDName(triggerName);
if (StringUtil.isBlank(groupName)) {
   groupName = Scheduler.DEFAULT_GROUP;
}
if (StringUtil.isBlank(jobName)) {
   log.error("jobName can't be null");
   throw new RuntimeException("jobName can't be null");
}
try {
   CronTrigger cronTrigger = new CronTrigger(triggerName, groupName,
     jobName, groupName);
   cronTrigger.setCronExpression(cronExpression);
   scheduler.scheduleJob(cronTrigger);
} catch (SchedulerException e) {
   throw new RuntimeException(e);
}
}
// 创建一个触发器,定时启动,每隔n秒启动一次,定时停止
public void addTrigger(String triggerName, long n, String groupName,
   String jobName, Date startTime, Date endTime) {
if (startTime == null) {
   startTime = new Date();
}
addTrigger(triggerName, startTime, endTime,
   SimpleTrigger.REPEAT_INDEFINITELY, n * 1000L, groupName,jobName);
}
// 触发器真实新增方法
private void addTrigger(String triggerName, Date startTime, Date endTime,
   int repeatCount, long repeatInterval, String groupName,
   String jobName) {
triggerName = StringUtil.getUUIDName(triggerName);
if (StringUtil.isBlank(groupName)) {
   groupName = Scheduler.DEFAULT_GROUP;
}
if (StringUtil.isBlank(jobName)) {
   log.error("jobName can't be null");
   throw new RuntimeException("jobName can't be null");
}
try {
   SimpleTrigger SimpleTrigger = new SimpleTrigger(triggerName,
     groupName, jobName, groupName, startTime, endTime,
     repeatCount, repeatInterval);
   scheduler.scheduleJob(SimpleTrigger);
} catch (SchedulerException e) {
   throw new RuntimeException(e);
}
}
// 返回所有triggers
public List<Map<String, Object>> getQrtzTriggers() {
return quartzDAO.getQrtzTriggers();
}
// 返回所有jobs
public List<Map<String, Object>> getQrtzJobs() {
return quartzDAO.getOrtzJobs();
}
// 暂停trigger
public void pauseTrigger(String triggerName, String groupName) {
if (StringUtil.isBlank(triggerName)) {
   throw new RuntimeException(
     "triggerName can't be null when pauseTrigger!");
}
if (StringUtil.isBlank(groupName)) {
   groupName = Scheduler.DEFAULT_GROUP;
}
try {
   scheduler.pauseTrigger(triggerName, groupName);// 停止触发器
} catch (SchedulerException e) {
   throw new RuntimeException(e);
}
}
// 暂停job
public void pauseJob(String jobName, String groupName) {
if (StringUtil.isBlank(jobName)) {
   throw new RuntimeException("jobName can't be null when pauseJob!");
}
if (StringUtil.isBlank(groupName)) {
   groupName = Scheduler.DEFAULT_GROUP;
}
try {
   scheduler.pauseJob(jobName, groupName); // 停止任务
} catch (SchedulerException e) {
   throw new RuntimeException(e);
}
}
// 重启trigger
public void resumeTrigger(String triggerName, String groupName) {
if (StringUtil.isBlank(triggerName)) {
   throw new RuntimeException(
     "triggerName can't be null when resumeTrigger!");
}
if (StringUtil.isBlank(groupName)) {
   groupName = Scheduler.DEFAULT_GROUP;
}
try {
   scheduler.resumeTrigger(triggerName, groupName);// 重启触发器
} catch (SchedulerException e) {
   throw new RuntimeException(e);
}
}
// 重启job
public void resumeJob(String jobName, String groupName) {
if (StringUtil.isBlank(jobName)) {
   throw new RuntimeException("jobName can't be null when resumeJob!");
}
if (StringUtil.isBlank(groupName)) {
   groupName = Scheduler.DEFAULT_GROUP;
}
try {
   scheduler.resumeJob(jobName, groupName); // 重启任务
} catch (SchedulerException e) {
   throw new RuntimeException(e);
}
}
// 删除trigger
public boolean removeTrigger(String triggerName, String groupName) {
if (StringUtil.isBlank(triggerName)) {
   throw new RuntimeException(
    "triggerName can't be null when removeTrigger!");
}
if (StringUtil.isBlank(groupName)) {
   groupName = Scheduler.DEFAULT_GROUP;
}
try {
   scheduler.pauseTrigger(triggerName, groupName);// 停止触发器
   return scheduler.unscheduleJob(triggerName, groupName);// 移除触发器
} catch (SchedulerException e) {
   throw new RuntimeException(e);
}
}
// 删除job
public boolean removeJob(String jobName, String groupName) {
if (StringUtil.isBlank(jobName)) {
   throw new RuntimeException("jobName can't be null when removeJob!");
}
if (StringUtil.isBlank(groupName)) {
   groupName = Scheduler.DEFAULT_GROUP;
}
try {
   scheduler.pauseJob(jobName, groupName);// 停止任务
   return scheduler.deleteJob(jobName, groupName);// 删除job
} catch (SchedulerException e) {
   throw new RuntimeException(e);
}
}
在spring的配置文件上,和quartz相关的配置只有如下,quartz-context.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean name="quartzScheduler"
   class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
   <property name="dataSource" ref="dataSource" />
   <property name="applicationContextSchedulerContextKey" value="applicationContextKey" />
   <property name="configLocation" value="classpath:quartz.properties" />
   <!-- 延时启动,这个很重要,必须要有足够长的时间让你的应用先启动完成后再让 Scheduler启动,
   这里设置60秒,如果你的应用启动时间较长,要相应增加startupDelay的时间-->
   <property name="startupDelay" value="60"/>
   <property name="overwriteExistingJobs" value="true" />
</bean>
</beans>
另外其中引用到的一个quartz.properties:
org.quartz.scheduler.instanceName=DefaultQuartzScheduler
org.quartz.scheduler.rmi.export=false
org.quartz.scheduler.rmi.proxy=false
org.quartz.scheduler.wrapJobExecutionInUserTransaction=false
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=10
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
org.quartz.jobStore.misfireThreshold=60000
#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
#org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.HSQLDBDelegate
#mysql使用如下配置
#org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#oracle使用如下配置
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
#org.quartz.jobStore.useProperties=true
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=false
org.quartz.jobStore.maxMisfiresToHandleAtATime=1
另外,这里例举一些在搜索文档时,看到的cron表达式举例:
"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触发

和quartz相关的东东就是这么多了,主要的新增添加等功能,都是通过SchedulerServiceImpl来完成的,两个搜索是通过自己写的DAO实现去搜索数据库的来的。具体项目请参考tasksupervisor
分享到:
评论

相关推荐

    定时任务管理-quartz.zip

    Quartz是一款开源的作业调度框架,它允许开发者创建、调度和执行定时任务。...总之,Quartz是一个功能强大的定时任务管理工具,对于任何需要进行定时任务处理的Java项目,都是一个值得考虑的选择。

    Springboot2-Quartz 后台可动态配置的定时任务

    本项目“Springboot2-Quartz 后台可动态配置的定时任务”是基于SpringBoot 2.x版本与Quartz Scheduler整合的一个示例,它展示了如何在后台管理系统中动态地创建、更新和删除定时任务,以及监控这些任务的状态,为...

    dotnet-用abpvNext快速开发QuartzNET定时任务管理界面

    Quartz.NET是一个开源的作业调度框架,它为.NET应用程序提供了强大的定时任务管理能力。而ABP (Application Blocks for .NET) 框架,尤其是其最新的版本abp vNext,是一个强大的企业级应用开发平台,它简化了开发...

    quartz动态添加、修改和删除定时任务

    Quartz是一款开源的作业调度框架,它允许开发者创建、安排和管理定时任务。在Java应用程序中,Quartz常被用来实现...通过熟练掌握Job、Trigger、Scheduler和JobDetail的使用,我们可以构建出强大的定时任务管理系统。

    定时任务完整案例 Java quartz

    【标题】"定时任务完整案例 Java quartz" 涉及的核心技术是Java的调度库Quartz,它是一个开源的工作调度框架,广泛应用于企业级应用中,用于执行定时任务。Quartz能够帮助开发者创建、调度和执行任务,实现高度灵活...

    Quartz定时任务表达式

    Quartz是一个开源的作业调度框架,能够触发在指定时间运行的任务,广泛应用于Java应用程序中进行定时任务的管理。Quartz的核心是Cron表达式,它允许开发者以一种灵活且可读性高的方式定义任务的执行时间。 #### ...

    spring+quartz实现定时任务动态管理

    总结来说,这个项目展示了如何结合Spring、Quartz、jQuery、Bootstrap和MyBatis分页插件,构建一个功能完善的定时任务管理系统。通过这个系统,开发者和管理员可以轻松地对定时任务进行动态管理,提高工作效率,同时...

    Quartz定时任务简单列子

    Quartz是一款开源的作业调度框架,它允许在Java应用程序中创建和管理定时任务。这个"Quartz定时任务简单列子"可能是一个简单的教程或者示例项目,用于展示如何在Java应用中集成和使用Quartz来执行预定的任务。 ...

    一个最简单的定时任务Quartz的例子

    在这个最简单的Quartz例子中,我们将探讨如何设置和运行一个基本的定时任务。 首先,我们需要了解Quartz的核心组件:Job和Trigger。Job是实际执行的工作单元,而Trigger则是触发Job执行的时间规则。在Quartz中,...

    Quartz定时任务常用的11张数据库脚本表结构

    了解这些表的结构和作用,可以帮助我们更好地理解和管理Quartz定时任务,包括创建、查询、更新和删除任务。在实际应用中,可以结合Quartz API进行相应的数据库操作,实现灵活的任务调度和管理。希望这些信息能对您在...

    使用Quartz执行定时任务

    Quartz是一款功能强大的开源Java定时任务框架,常用于在企业级应用中实现定时调度任务。它允许开发者定义作业(Jobs)和触发器(Triggers),并由Scheduler负责管理和执行这些任务。Quartz的核心优势在于其灵活性和...

    .net Quartz定时任务实例

    .NET中的Quartz是一个强大的、完全开源的作业调度框架,它为开发者提供了在应用程序中创建和管理定时任务的能力。Quartz可以被集成到任何Java应用程序中,无论是简单的应用程序还是复杂的多服务器集群环境。在这个...

    任务管理API quartz

    Quartz常用于定时任务场景,例如发送邮件通知、数据同步、定期备份、系统维护等。通过灵活的调度策略,开发者可以轻松实现复杂的时间控制需求。 总结,Quartz是一个强大且灵活的任务调度框架,其API提供了丰富的...

    spring2.0 Quartz 执行每天定时任务 建议用quartz-all-1.8.4.jar更稳定,兼容性更好

    引入后,你需要配置Spring的ApplicationContext,声明一个SchedulerFactoryBean,它会创建并管理Quartz的Scheduler实例。 接下来,定义Job类,该类需要实现`org.quartz.Job`接口或继承`org.quartz.StatefulJob`...

    定时任务框架Quartz Demo

    Quartz是一款开源的Java定时任务框架,用于在Java应用程序中创建和管理定时任务。它提供了丰富的API和功能,使得开发者可以灵活地定义和调度任务,实现应用中的周期性任务执行。在"定时任务框架Quartz Demo"项目中,...

    定时任务管理带WEB管理界面-quartz-web.zip

    总的来说,Quartz-Web提供了一个强大而灵活的定时任务管理系统,结合了Quartz Scheduler的强大功能和Web界面的便利性,是Java开发者进行定时任务管理的有力工具。无论是简单的日常任务还是复杂的调度需求,Quartz-...

    quartz定时任务Demo,直接可运行

    - 了解如何在Web应用(如Spring Boot)中集成Quartz,创建一个启动时自动加载的定时任务。 - 学习如何动态管理任务,如添加、删除、暂停和恢复定时任务。 这个Demo提供了一个很好的起点,帮助开发者快速上手...

    Java使用quartz实现任务调度定时任务

    Quartz库提供了一个灵活的API,可以创建、调度和管理任务,这些任务被称为Job。每个Job都与一个Trigger关联,Trigger定义了何时启动Job。在Java应用中,我们可以创建自定义的Job类,继承自`org.quartz.Job`接口,并...

    实现动态管理的quartz定时任务

    最后,尽管这个实现可能没有进行过多的优化,但作为参考,它展示了如何结合Quartz和数据库来实现动态的定时任务管理。通过这种方式,开发者可以根据业务需求灵活地调整任务执行策略,而无需每次都重启应用程序。 ...

    spring定时任务之Quartz

    需要注意的是,`ssh2Test`这个文件名可能与本主题无关,因为它是SSH2测试相关的,而SSH2通常指的是Secure Shell 2协议,用于远程访问和管理服务器,与Spring定时任务或Quartz不直接相关。如果需要了解更多关于SSH2的...

Global site tag (gtag.js) - Google Analytics