【问题标题】:Firing Quartz jobs manually手动触发 Quartz 作业
【发布时间】:2011-10-25 17:47:33
【问题描述】:

我们的应用程序中配置了多个 Quartz 作业。在开发过程中,我们让石英调度程序处于待机状态 - 但是,我们有时想要手动启动作业(出于开发目的)。如果我调用 fireTrigger,它会告诉我需要启动调度程序。但是,如果我启动调度程序,它也会立即调度所有其他作业,这不是我想要的(因为它们可能会在我调试手动触发的作业时触发)。

我可以在启动调度程序时暂停所有触发器,但随后我必须处理失火指令等。

是否有一种简单的方法可以手动启动作业,而无需处理暂停和失火(即即使调度程序处于待机状态也可以工作的 fireTrigger)?

【问题讨论】:

    标签: java quartz-scheduler


    【解决方案1】:

    所有在 Quartz Scheduler 中注册的 Job 都由一个由 name 和 group 组成的 JobKey 唯一标识。您可以通过调用调度程序实例的triggerJob(JobKey jobKey) 立即触发具有给定 JobKey 的作业。

    // Create a new Job 
    JobKey jobKey = JobKey.jobKey("myNewJob", "myJobGroup");
    JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity(jobKey).storeDurably().build();
    
    // Register this job to the scheduler
    scheduler.addJob(job, true);
    
    // Immediately fire the Job MyJob.class
    scheduler.triggerJob(jobKey);
    

    注意:

  • scheduler 是整个应用程序中使用的调度程序实例。它的 start() 方法应该在创建后就已经被调用了。
  • 该作业是不能附加任何触发器或 cron 的持久作业。它只能通过调用 `triggerJob(JobKey jobKey)` 以编程方式触发。
  • 【讨论】:

      【解决方案2】:

      这是手动触发作业所需的循环:

      SchedulerFactory stdSchedulerFactory = new StdSchedulerFactory();
      Scheduler scheduler = stdSchedulerFactory.getScheduler();
      
      // loop jobs by group
      for (String groupName : scheduler.getJobGroupNames()) {
          // get jobkey
          for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
              String jobName = jobKey.getName();
              String jobGroup = jobKey.getGroup();
              scheduler.triggerJob(jobName, jobGroup);
          }
      }
      

      【讨论】:

      • 在 2.2.1 上不再工作,因为 triggerJob() 将 JobKey 作为参数。 See doc 改用@Minarul-Haque 响应
      【解决方案3】:

      不需要start-timeend-time

      <trigger>
            <cron>
              <name>TestTrigger</name>
              <group>CronSampleTrigger</group>
              <description>CronSampleTrigger</description>
              <job-name>TestJob</job-name>
              <job-group>jobGroup1</job-group>    
      
          <!--<start-time>1982-06-28T18:15:00.0Z</start-time>
              <end-time>2020-05-04T18:13:51.0Z</end-time>-->
      
              <cron-expression>0 0/1 * * * ?</cron-expression>
            </cron>
       </trigger>
      

      【讨论】:

        【解决方案4】:

        您可以尝试在调度程序中添加触发器过滤器

        this.scheduler.addGlobalTriggerListener(new DebugExecutionFilter());
        

        当执行不是易失性(未计划立即运行)并且您处于调试模式时,调试执行过滤器将添加否决权。

        这是一个实现示例:

        private static class DebugExecutionFilter implements TriggerListener
        {
        
            public DebugExecutionFilter()
            {
            }
        
            @Override
            public String getName()
            {
                return "Task execution filter";
            }
        
            @Override
            public void triggerFired(Trigger trigger, JobExecutionContext context)
            {
                // Do nothing
            }
        
            /* (non-Javadoc)
             * 
             * @see org.quartz.TriggerListener#vetoJobExecution(org.quartz.Trigger, org.quartz.JobExecutionContext) */
            @Override
            @SuppressWarnings("unchecked")
            /**
             * A veto is added if :
             *  - For non volatile trigger if we are in debug mode
             */
            public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context)
            {
        
                try
                {
                    // 
                    if ( !trigger.isVolatile() && isDebugMode() )
                    {
                        return true;
                    }
        
                    //task is run by scheduler.triggerJobWithVolatileTrigger() for immediate schedule
                    //or task is schedule and we are not in debugMode
                    return false;
            }
        
        
            @Override
            public void triggerMisfired(Trigger trigger)
            {
                // do nothing
            }
        
            @Override
            public void triggerComplete(Trigger trigger, JobExecutionContext context, int triggerInstructionCode)
            {
                // do nothing
            }
        
        }
        

        【讨论】:

        • 感谢mmounirou的回答!也许我没有准确描述这个问题,但我确实希望在开发模式下触发非暂停触发器。只是在开发模式下,调度程序处于待机状态,所有触发器默认暂停。如果我现在转到我们的计划作业页面并启动其中一个调度程序以手动运行其中一个作业(在每个作业旁边,我们有一个“立即运行”按钮),那么所有其他作业都会开始失败。我基本上希望暂停的工作在开发模式下不做任何事情 - 是否有一种全球性的方法可以做到这一点?
        猜你喜欢
        • 2011-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-04
        • 1970-01-01
        • 2016-08-10
        • 2019-04-28
        • 1970-01-01
        相关资源
        最近更新 更多