简体   繁体   English

如何在 Spring 引导应用程序中测试石英作业的正常工作

[英]How to test proper working of Quartz job in Spring Boot application

I want to test if my Quartz trigger is working as it supposes in practice.我想测试我的 Quartz 触发器在实践中是否正常工作。 My Quartz configuration looks like:我的 Quartz 配置如下所示:

@Configuration
public class QuartzConfiguration {

  @Bean
  public JobDetail verificationTokenRemoverJobDetails() {
    return
        JobBuilder
            .newJob(VerificationTokenQuartzRemoverJob.class)
            .withIdentity("Job for verification token remover")
            .storeDurably()
            .build();
  }

  @Bean
  public Trigger verificationTokenRemoverJobTrigger(JobDetail jobADetails) {
    return
        TriggerBuilder
            .newTrigger()
            .forJob(jobADetails)
            .withIdentity("Trigger for verification token remover")
            .withSchedule(CronScheduleBuilder.cronSchedule("0 0 0/2 1/1 * ? *"))
            .build();
  }
}

and my Job class looks like:我的工作 class 看起来像:

@AllArgsConstructor
public class VerificationTokenQuartzRemoverJob implements Job {

  private VerificationTokenRepository verificationTokenRepository;

  @Override
  public void execute(JobExecutionContext context) {
    verificationTokenRepository.deleteAllByCreatedLessThan(LocalDateTime.now().minusMinutes(30));
  }
}

When I am starting my Spring Boot application in logs I can realize that Job is working and triggered cyclical but it's not enough to confirm the proper working.当我在日志中启动我的 Spring 引导应用程序时,我可以意识到 Job 正在工作并周期性触发,但不足以确认正常工作。

That's why I decided to create a JUnit test.这就是我决定创建 JUnit 测试的原因。 I found a tutorial: click but an owner used a clause while(true) which according to this topic: click is not a preferable option.我找到了一个教程:单击但所有者使用了一个子句 while(true),根据此主题: 单击不是一个更可取的选项。 Here occurs a question, is there any other option to verify the Job class name, the identity of the trigger and check if CRON expression and the concrete job are called as often as possible?这里出现一个问题,是否有任何其他选项来验证作业 class 名称、触发器的身份并检查是否尽可能频繁地调用 CRON 表达式和具体作业?

If it possible I will be grateful for suggestions on how to reach a desirable effect.如果可能的话,我将不胜感激有关如何达到理想效果的建议。

Please not that the above answer on using the Spring Scheduling has one big drawback: This works nicely if you just run a single instance of your application, but as soon as you scale up to multiple instances it becomes more complex: You might want to run the job only once at a certain interval but if two nodes run simultaneously the job might run on both nodes (so basically twice).请注意,上述关于使用 Spring 调度的答案有一个很大的缺点:如果您只运行应用程序的单个实例,这会很好地工作,但是一旦扩展到多个实例,它就会变得更加复杂:您可能想要运行该作业仅在某个时间间隔内运行一次,但如果两个节点同时运行,则该作业可能会在两个节点上运行(基本上是两次)。 Quartz can handle these kind of situations because it can have a central database through which it can coordinate if a job is already started. Quartz 可以处理这类情况,因为它可以有一个中央数据库,如果作业已经开始,它可以通过该数据库进行协调。 With spring scheduling the job will run on both nodes.使用 spring 调度,作业将在两个节点上运行。

With SpringBoot, You could do easier doing the following使用 SpringBoot,您可以更轻松地执行以下操作

--- Option 1 --- - - 选项1 - -

@Configuration
// This is important!
@EnableScheduling
public class Configuration{
 // TODO Change to 0 0 0/2 1/1 * ? *
 @Scheduled(cron = "0 15 10 15 * ?")
 public void scheduleTaskUsingCronExpression() {

    long now = System.currentTimeMillis() / 1000;
     System.out.println(
        "schedule tasks using cron jobs - " + now);
  }      

} }

Full Example: https://www.baeldung.com/spring-scheduled-tasks完整示例: https://www.baeldung.com/spring-scheduled-tasks

--- Option 2-> Programatically --- --- 选项 2-> 以编程方式 ---

@Configuration
@EnableScheduling

public class Configuration implements SchedulingConfigurer {
   @Bean(destroyMethod = "shutdown")
   public Executor taskExecutor() {
      return Executors.newScheduledThreadPool(100);
   }

    @Override
            public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
            CronTrigger cronTrigger
            = new CronTrigger("* * * * * *");

                    taskRegistrar.setScheduler(taskExecutor());
                    taskRegistrar.addTriggerTask(
                            new Runnable() {
                                @Override public void run() {
                                    System.out.println("RUN!!!");
                                }
                            },
                            cronTrigger
                    );
                }

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM