基于RAMJobStore开发出现的几个问题

1.更新任务java

先前咱们在更新任务时,虽然更新了定时任务的执行时间,可是并无对参数进行更新,即便用context.getMergedJobDataMap().get(...)方法获取到的参数仍是旧的。web

假设咱们更新了任务的时间表达式,任务已按新的时间表达式在执行,但在获取到参数后发现时间表达式仍是原来的。spring

尝试对参数进行更新,使用以下代码:编程

JobDetail jobDetail = scheduler.getJobDetail(getJobKey(jobName, jobGroup));
//jobDetail = jobDetail.getJobBuilder().ofType(jobClass).build();
//更新参数 实际测试中发现没法更新
JobDataMap jobDataMap = jobDetail.getJobDataMap();
jobDataMap.put(ScheduleJobVo.JOB_PARAM_KEY, param);
jobDetail.getJobBuilder().usingJobData(jobDataMap);

发现没法更新,试过其它几个api发现都不行,没有办法,最后采用了先删除任务再进行建立的方式来迂回实现参数的更新。更新任务有直接修改方式和删除修改方式,区别就在这里。下面先删后加的方式更新Jobapi

Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.deleteJob(jobKey);
//修改cronTrigger 
//根据TriggerKey和Trigger从新添加一个Job到scheduler  
 scheduler.addJob...

2.任务的同步和异步tomcat

在定时任务运行时更新是没有办法改变同步和异步的app

同步和异步在quartz 2.2的版本中对于使用者来讲区别只在因而否在job类上添加了@DisallowConcurrentExecution注解webapp

整合使用时,碰到的一些问题:异步

1、更新任务时参数问题。也就是前面说的没法更新任务中传入的参数。分布式

2、同步或异步在定时任务运行时修改是不能改变的,这个在前面也提到了。

3、在定时任务运行时修改,可能会该让任务长时间处于线程阻塞状态,即BLOCKED状态,即便你的任务中只有简单的一行System.out输出。要使它恢复也很简单,删除重建便可。

4、定时任务运行两次的问题。这个也是网上传的最多的问题,这里来着重的说一下。

网上流传引发该问题的缘由目前主要有两个说法:

1 spring配置文件加载了屡次,致使quartz的bean被实例化屡次而致使任务屡次执行。

2 tomcat的webapps目录问题。tomcat运行时加载了两次配置文件致使任务屡次执行。

这两个说法在个人demo中应该并不存在,但为了验证我也尝试了下。

不使用tomcat,在main方法中用编程的方式启动spring,甚至不使用spring,直接用quartz官方给出的代码:

try {     // Grab the Scheduler instance from the Factory      Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();     // and start it off     scheduler.start();     scheduler.shutdown(); } catch (SchedulerException se) {     se.printStackTrace(); }

问题仍是存在,这就说明不是配置文件加载的问题了,这应该是quartz自己存在的一个bug,并且这个屡次运行是颇有规律的,基本按以下套路走:

  • 定为5秒运行一次,一切正常,没有屡次执行现象发生。

  • 定为10秒运行一次,一切正常,没有屡次执行现象发生。

  • 定为29秒运行一次,运行时一次正常,一次不正常。

  • 定为59秒运行一次,运行时一次正常,一次不正常。

以上是我实测得出的,再长时间就没测了,毕竟太耗时。在有运行两次的现象时都是间隔的,即一次正常一次不正常这种方式。

既然推断是quartz自己存在bug,那咱们又要如何解决这个问题了?

其实在我我的看来,这个问题是可有可无的,为何说可有可无呢?这就涉及到你项目业务设计的是否完善,代码是否健壮了。

一个设计良好的业务方法,特别是那些供外部调用的接口或方法,应该都支持幂等性,何为幂等性?即这个方法一样的参数至少在一个时间区间内,我调用1次和调用10次100次,结果都是同样的。

支持了幂等性,前面说的运行两次的状况是否是就可有可无了?在有些定时任务为分布式设计的系统(后面会探讨)中,为了确保定时任务的执行甚至会故意人为的去调用两次。

固然支持幂等性最好是在进入方法时就判断,发现已经执行过期就当即返回而不是真的再去一样的结果再执行一遍,以节省资源。

相关文章
相关标签/搜索