2011-01-28 2 views
1

Quartz Enterprise Job Scheduler (1.8.3)를 사용하고 있습니다. 작업 구성은 여러 xml 파일에서 이루어지며이 xml 파일의 변경 사항을 감지하고 작업을 다시 예약하는 특별한 작업이 있습니다. 이것은 멋쟁이지만, 문제는 "스케줄러 작업"이 필요하다는 것입니다. 일단이 일이 그 자체를 다시 계획하면, 나는 그것이 여러 번 실행되는 것을 본다. 그래도 예외는 없습니다.Quartz Enterprise Scheduler : 자체 일정을 계획하는 작업

나는 문제를 복제하고 격리 시켰습니다. 이 엔트리 포인트가 될 것입니다 :

public class App { 
    public static void main(final String[] args) throws ParseException, SchedulerException { 
    // get the scheduler from the factory 
    final Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); 

    // start the scheduler 
    scheduler.start(); 

    // schedule the job to run every 20 seconds 
    final JobDetail jobDetail = new JobDetail("jobname", "groupname", TestJob.class);   
    final Trigger trigger = new CronTrigger("triggername", "groupname", "*/20 * * * * ?"); 

    // set the scheduler in the job data map, so the job can re-configure itself 
    jobDetail.getJobDataMap().put("scheduler", scheduler); 

    // schedule job 
    scheduler.scheduleJob(jobDetail, trigger); 

    } 
} 

그리고이 작업 클래스 다음과 같습니다

public class TestJob implements Job { 

private final static Logger LOG = Logger.getLogger(TestJob.class); 
private final static AtomicInteger jobExecutionCount = new AtomicInteger(0); 

public void execute(final JobExecutionContext context) throws JobExecutionException { 
    // get the scheduler from the data map 
    final Scheduler scheduler = (Scheduler) context.getJobDetail().getJobDataMap().get("scheduler"); 
    LOG.info("running job! " + jobExecutionCount.incrementAndGet()); 

    // buid the job detail and trigger 
    final JobDetail jobDetail = new JobDetail("jobname", "groupname", TestJob.class); 
    // this time, schedule it to run every 35 secs 
    final Trigger trigger; 
    try { 
     trigger = new CronTrigger("triggername", "groupname", "*/50 * * * * ?"); 
    } catch (final ParseException e) { 
     throw new JobExecutionException(e); 
    } 
    trigger.setJobName("jobname"); 
    trigger.setJobGroup("groupname"); 

    // set the scheduler in the job data map, so this job can re-configure itself 
    jobDetail.getJobDataMap().put("scheduler", scheduler); 

    try { 
     scheduler.rescheduleJob(trigger.getName(), jobDetail.getGroup(), trigger); 
    } catch (final SchedulerException e) { 
     throw new JobExecutionException(e); 
    } 
} 
} 

내가 scheduler.rescheduleJobscheduler.deleteJob 다음 scheduler.scheduleJob으로 모두를 시도했습니다. 22 : 20018, 작업이 잘 실행 23에서 어떻게

23:22:15,874   INFO SchedulerSignalerImpl:60 - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl 
23:22:15,878   INFO QuartzScheduler:219 - Quartz Scheduler v.1.8.3 created. 
23:22:15,883   INFO RAMJobStore:139 - RAMJobStore initialized. 
23:22:15,885   INFO QuartzScheduler:241 - Scheduler meta-data: Quartz Scheduler (v1.8.3) 

'MyScheduler' with instanceId '1' 
    Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally. 
    NOT STARTED. 
    Currently in standby mode. 
    Number of jobs executed: 0 
    Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 3 threads. 
    Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered. 

23:22:15,885   INFO StdSchedulerFactory:1275 - Quartz scheduler 'MyScheduler' initialized from default resource file in Quartz package: 'quartz.properties' 
23:22:15,886   INFO StdSchedulerFactory:1279 - Quartz scheduler version: 1.8.3 
23:22:15,886   INFO QuartzScheduler:497 - Scheduler MyScheduler_$_1 started. 
23:22:20,018   INFO TestJob:26 - running job! 1 
23:22:50,004   INFO TestJob:26 - running job! 2 
23:22:50,010   INFO TestJob:26 - running job! 3 
23:22:50,014   INFO TestJob:26 - running job! 4 
23:22:50,016   INFO TestJob:26 - running job! 5 
... 
23:22:50,999   INFO TestJob:26 - running job! 672 
23:22:51,000   INFO TestJob:26 - running job! 673 

주의 사항 : 아무리 내가 뭘, 이것은 내가 (내가 log4j를 사용하고 있습니다) 얻을 출력은 없다. 이 시점에서 작업은 50 초마다 실행되도록 일정을 재조정합니다. 다음에 실행될 때 (23 : 22 : 50,004), 그것은 수 백번 예정되어 있습니다.

작업을 구성하는 방법에 대한 아이디어가 있습니까? 해당 작업을 실행 하시겠습니까? 내가 도대체 ​​뭘 잘못하고있는 겁니까?

감사합니다!

답변

5

쉬운.

먼저 Cron Expressions에 대한 몇 가지 오해가 있습니다. "*/20 * * * *?" 주석이 의미하는대로 매 20 초이지만, 60은 균등하게 20으로 나눌 수 있기 때문에. "/50 ..."은 매 50 초가 아닙니다. 매분 0 초와 50 초입니다. 또 다른 예로 "/13 ..."은 1 분마다 초 0, 13, 26, 39 및 52입니다. 따라서 두 번째 52와 다음 분의 0 초 사이에는 13이 아니라 8 초뿐입니다. */50 발사마다 50 초, 다른 발포 사이에는 10 초를 얻습니다.

하지만 그로 인해 급속하게 일하는 것은 아닙니다. 문제는 현재의 초가 "50"이고 새 트리거가 두 번째 "50"에서 시작되도록 예약 했으므로 즉시 트리거합니다. 그리고 여전히 두 번째 50이며 작업이 다시 실행되고 두 번째 트리거가 두 번째 50에서 실행되도록 예약하고, 계속해서 50 번째 초 동안 여러 번 트리거합니다.

트리거의 시작 시간을 미래 (최소 1 초)로 설정하거나 일정이 현재 초와 일치하는 경우 일정을 잡은 초에 트리거해야합니다.

또한 모든 "N"초 유형의 일정이 필요한 경우 CronTrigger보다는 SimpleTrigger를 제안합니다. SimpleTrigger는 "매 35 초마다"또는 "매 50 초마다"아무런 문제없이 사용할 수 있습니다. CronTrigger는 "1 월 매주 월요일 10시 15 분 45 초, 0시 15 분 40 분 43 분"과 같은 표현을 의미합니다.

+0

은 의미가 있습니다. 테스트 앱의 코드가 변경되었으며 현재 예상대로 작동합니다 ... 감사합니다. – chahuistle

관련 문제