Pregunta

Estoy usando Quartz Enterprise Job Scheduler (1.8.3). La configuración del trabajo proviene de varios archivos XML y tenemos un trabajo especial que detecta cambios en estos archivos XML y vuelve a programar trabajos. Esto funciona Dandy, pero el problema es que también necesito este "trabajo de programador" para volver a programarlo. Una vez que este trabajo se vuelve a programar, por alguna razón, veo que se ejecuta muchas veces. Sin embargo, no veo ninguna excepción.

He replicado y aislado el problema. Este sería el punto de entrada:

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);

    }
}

Y esta sería la clase de trabajo:

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);
    }
}
}

He probado ambos con scheduler.rescheduleJob y con scheduler.deleteJob después scheduler.scheduleJob. No importa lo que haga, esta es la salida que obtengo (estoy usando log4j):

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

Observe cómo a los 23: 22: 20,018, el trabajo funciona bien. En este punto, el trabajo se vuelve a programar para correr cada 50 segundos. La próxima vez que se ejecute (a las 23: 22: 50,004), se programa cientos de veces.

Cualquier idea sobre cómo configurar un trabajo tiempo ejecutar ese trabajo? ¿Qué estoy haciendo mal?

¡Gracias!

¿Fue útil?

Solución

Fácil.

En primer lugar, tienes un par de malentendidos sobre las expresiones cron. " */20 * * * *?" es cada veinte segundos como lo indica el comentario, pero solo porque 60 es uniformemente divisible para 20 "./50 ... "No es cada cincuenta segundos. Es segundos 0 y 50 de cada minuto. Como otro ejemplo", ",/13 ... "son segundos 0, 13, 26, 39 y 52 de cada minuto, así que entre el segundo 52 y el siguiente minuto 0 segundos, solo hay 8 segundos, no 13. Entonces, con */50 Obtenga 50 segundos entre cada otro disparo y 10 segundos entre los demás.

Sin embargo, esa no es la causa de su rápido disparo del trabajo. El problema es que el segundo actual es "50" y está programando el nuevo gatillo para disparar en el segundo "50", por lo que inmediatamente se dispara. Y luego sigue siendo el segundo 50, y el trabajo se ejecuta nuevamente, y programa otro desencadenante para disparar en el segundo 50, y así sucesivamente, tantas veces como puede durante el 50 segundo.

Debe establecer la hora de inicio del activador en el futuro (al menos un segundo) o disparará en el mismo segundo que lo está programando, si el horario coincide con el segundo actual.

Además, si realmente necesita cada tipo de horario de "n" segundos, sugiero SimpleTrigger en lugar de Crontrigger. SimpleTrigger puede hacer "cada 35 segundos" o "cada 50 segundos" no hay problema. Crontrigger está destinado a expresiones como "En los segundos 0, 15, 40 y 43 de los minutos 15 y 45 de las 10 horas en punto en todos los lunes de enero".

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top