在 spring 启动应用程序中安排多个批处理作业

scheduling more than one batch job in spring boot application

我的 spring 启动批处理应用程序有一个调度程序,它每小时将我在 FirstBatchConfiguration class 中编写的批处理作业安排到 运行。

我在同一个应用程序的 SecondBatchConfiguration class 中配置了另一个批处理作业,我将每周安排一次 运行,但我无法弄清楚如何在同一个 JobScheduler 中安排它,以便两个作业都应该 运行 在他们自己的计划时间。

如果有人能帮我实现这个。

我当前的调度程序是:

@Component
public class JobScheduler {

    @Autowired
    private JobLauncher jobLauncher;

    @Autowired
    private FirstBatchConfiguration firstBatchConfiguration;

    @Scheduled(cron = "0 0 0/1 * * ?")
    public void runJob() {

        Map<String, JobParameter> confMap = new HashMap<>();
        confMap.put("time", new JobParameter(System.currentTimeMillis()));
        JobParameters jobParameters = new JobParameters(confMap);
        final Logger logger = LoggerFactory.getLogger("applicationlogger");

        try {

            jobLauncher.run(firstBatchConfiguration.firstJob(), jobParameters);

        } catch (JobExecutionAlreadyRunningException | JobInstanceAlreadyCompleteException
                | JobParametersInvalidException | org.springframework.batch.core.repository.JobRestartException e) {

            logger.error(e.getMessage());
        }
    }

}

如果程序必须 运行 第二个计划,则添加一个带有计划注释的新方法,例如 @Scheduled(cron = "5 8 * * 6 ?")。如果您需要使用 SecondBatchConfiguration class,那么只需将其自动装配即可。

  1. 第 1 步(自动连接您的配置)@Autowired 您的 SecondBatchConfiguration

示例:

@Autowired
private SecondBatchConfiguration secondBatchConfiguration;
  1. 创建一个新方法并使用@Scheduled 注释对其进行调度,并在方法主体中启动第二个作业。

示例:

@Scheduled(cron = "5 8 * * 6 ?")
public void runSecondJob() { ... }

您可以根据需要拥有多个时间表,每个时间表都有自己的时间表。

@Scheduled(cron = "5 8 * * 6 ?")
public void runSecondJob() { .... }

@Scheduled(cron = "0 0 0/1 * * ?")
public void runJob() { .... }

编辑:异步作业执行

异步作业执行是 spring 批处理的一个非常强大的功能,有很好的文档和示例。

请参阅以下说明以激活异步作业异常:

Step 1: Add Job Configuration (this alternative is using In-Memory JobRepository). To read more about repository types go to Spring Documentation

创建 ResourcelessTransactionManager Bean

   @Bean
    public ResourcelessTransactionManager transactionManager() {
        return new ResourcelessTransactionManager();
    }

创建 MapJobRepositoryFactory Bean

@Bean
public MapJobRepositoryFactoryBean mapJobRepositoryFactory(
        ResourcelessTransactionManager txManager) throws Exception {
    MapJobRepositoryFactoryBean factory = new
            MapJobRepositoryFactoryBean(txManager);
    factory.afterPropertiesSet();
    return factory;
}

创建 JobRepository Bean

@Bean
public JobRepository jobRepository(
        MapJobRepositoryFactoryBean factory) throws Exception {
    return factory.getObject();
}

创建一个ThreadPoolExecutor(ThreadPoolExecutor负责Async执行,执行器的种类更多,你可以在Spring Documentation中了解更多)

@Bean
public ThreadPoolTaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
    taskExecutor.setCorePoolSize(5);
    taskExecutor.setMaxPoolSize(10);
    taskExecutor.setQueueCapacity(30);
    return taskExecutor;
}

创建一个 JobLauncher bean

   @Bean
    public JobLauncher jobLauncher(ThreadPoolTaskExecutor taskExecutor, JobRepository jobRepository){
        SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
        jobLauncher.setTaskExecutor(taskExecutor);
        jobLauncher.setJobRepository(jobRepository);
        return jobLauncher;
    }

Step 2: Enable Async Job Execution

去你Spring启动应用程序Class和下面的注释

@EnableBatchProcessing
@EnableAsync
@EnableScheduling
@SpringBootApplication
public class MyBatchApp {

默认情况下,Spring Boot 将只使用一个线程来执行所有计划任务 运行。这些任务将被阻塞。相反,我会将调度程序配置为 运行 单独线程中的每个计划任务:

@Configuration
public class SchedulerConfig implements SchedulingConfigurer
{    private final int POOL_SIZE = 10;
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar)
    {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();

        threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
        threadPoolTaskScheduler.setThreadNamePrefix("scheduled-task-pool-");
        threadPoolTaskScheduler.initialize();

        taskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }
}