Описание проблемы. У нас есть кварцевое задание, которое планируется запускать в разное время в течение дня, например, с 13 до 16 и 19 часов. Проблема в том, что задание запускается и выполняется в другое время, кроме запланированного.
Что мы сделали: мы уже пытались полностью выключить наши серверы (JBoss) и очистить кварцевые таблицы, но это вообще не сработало.
Мы используем кварц 1.6, и я хочу знать, есть ли какая-либо ошибка в версии и может ли обновление кварца решить проблему ИЛИ есть ли какие-либо проблемы с настройкой свойств кварца и можно ли изменить свойства для решения этой проблемы.
Изменить - подробнее см. ниже:
Я скорректировал время работы. Кроме того, задание запускается в любое случайное время, кроме тех, которые мы упомянули в его расписании. Нет никакой закономерности, когда он срабатывает, кроме запланированного времени.
Ниже приведены сведения о задании и триггере в файле свойств БД. На основе этих деталей задания и деталей триггера будут настроены в БД в таблицах Quartz_Triggers и Quartz_CronTrigger:
<job>
<job-detail>
<name>Match Job</name>
<group>JB_QUARTZ</group>
<job-class>com.qd.qehadmin.common.scheduler.MatchJob</job-class>
<volatility>false</volatility>
<durability>true</durability>
<recover>true</recover>
</job-detail>
<trigger>
<cron>
<name>Match Job Trigger</name>
<group>JB_QUARTZ</group>
<job-name>match Job</job-name>
<job-group>JB_QUARTZ</job-group>
<cron-expression>0 0 13,16,19 * * ?</cron-expression>
</cron>
</trigger>
</job>
Ниже приведены подробные сведения о свойствах кварца в БД:
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName = JB_QUARTZ
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = true
org.quartz.jobStore.dataSource = jobSchedulerDS
org.quartz.jobStore.tablePrefix = JB_QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 10000
#============================================================================
# Configure Datasources
#============================================================================
org.quartz.dataSource.jobSchedulerDS.jndiURL=java:JBAPI
org.quartz.dataSource.jobSchedulerDS.java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
#java.naming.provider.url=jnp://localhost:3099
java.naming.provider.url=jnp://166.20.337.12:8441,166.20.337.14:8441,166.20.337.16:8441,166.20.337.19:8441
#============================================================================
Ниже приведен Java-код для работы:
public void execute(JobExecutionContext ctx) throws JobExecutionException
{
try{
//Scheduler scheduler = new StdSchedulerFactory().getScheduler();
SendEmail sm = new SendEmail();
boolean running = false;
if (ctx.getJobDetail().getKey().getName().equalsIgnoreCase("match Job") ) {
LogFile.MATCH_JOB.logInfo("Match jobs size : "+ctx.getScheduler().getCurrentlyExecutingJobs().size(), this.getClass().getName());
if(ctx.getScheduler().getCurrentlyExecutingJobs().size()==1)
{
initClient(); //This method will read properties from DB
startTime=System.currentTimeMillis();
Match(); //This method will execute job level code
endTime=System.currentTimeMillis();
LogFile.MATCH_JOB.logInfo("***Match job ends*** Loadtest: "+Constants.loadTest+" in time: "+(endTime-startTime)/1000 + "secs", this.getClass().getName());
}
else
{
running=true;
}
}
if(running)
{
LogFile.MATCH_JOB.logInfo("The Match job is already running – sending email",this.getClass().getName());
sm.sendEmail();
}
}catch(Exception e){
e.printStackTrace();
LogFile.MATCH_JOB.logError("***Match Job Error*** " +e.getStackTrace(), this.getClass().getName());
}
}
0 0 7,13,19 * * ?
, например на cronmaker.com, время: 13:00, 19:00 и 7:00. , а это не то, что вы хотите, согласно тому, что вы написали в своем вопросе. - person yishaiz   schedule 18.09.2017getCurrentlyExecutingJobs()
. См. Этот ответ stackoverflow.com/a/27395623/3883957 и в нем говорится Также обратите внимание, что этот метод не с учетом кластера, а также не забудьте не использовать его в классе Job, так что, возможно, это вызывает проблемы. - person yishaiz   schedule 27.09.2017ctx
- это текущее задание, аjobCtx
находится в цикле всех CurrentExecutingJobs, каждый раз, когда он сравнивает другое задание с текущим заданием. Но это не так важно, важно то, что я процитировал: использованиеgetCurrentlyExecutingJobs
не зависит от кластера и не забывайте не использовать его в классе Job. Вы можете попробовать, например, отказаться от использования этого и просто посмотреть, исправляет ли это время срабатывания триггера. Кроме того, Вы не ответили на мои предыдущие вопросы, поэтому для меня будет сложно помочь больше. - person yishaiz   schedule 09.10.2017StatefulJob
, и Quartz позаботится об этом - см. Этот ответ stackoverflow.com/a/1638573 / 3883957. И тогда вам не понадобитсяgetCurrentlyExecutingJobs
. Что касается версии Quartz 1.6, вы можете захотеть обновить ее как минимум до 1.6.6 (если не до более новой версии ...), потому что кажется, что в 1.6.0 много ошибок. Например, посмотрите, что они говорят в комментариях jira.terracotta.org/jira/browse / QTZ-311 - person yishaiz   schedule 29.10.2017StatefulJob
? - person yishaiz   schedule 15.11.2017