Spring 批处理作业调度程序在运行几次后停止执行

Spring Batch Job scheduler stops being executing after several runs

在一个项目中,我们必须 运行 一个定期启动的作业(现在在 QA env 上每 5 分钟一次)为 40k 用户处理一些分配。 我们决定使用 Spring Batch,因为它非常适合并使用几乎默认配置实现它(例如,它在引擎盖下使用 SyncTaskExecutor)。 好的,所以,有一个作业由一个步骤组成:

  1. 开箱即用 HibernatePagingItemReader
  2. 在内存中执行轻量级计算的自定义ItemProcessor
  3. 自定义 ItemWriter 通过多个 JPQL 和本机查询将数据保存到同一个 PostgreSQL 数据库。

作业本身使用 @EnableScheduling 安排,并且每 5 分钟由 cron 表达式触发:

@Scheduled(cron = "${job.assignment-rules}")
void processAssignments() {
  try {
    log.debug("Running assignment processing job");
    jobLauncher.run(assignmentProcessingJob, populateJobParameters());
  } catch (JobExecutionException e) {
    log.error("Job processing has failed", e);
  }
}

这是来自 application.yml 的 cron 表达式:

job:
  assignment-rules: "0 0/5  * * * *"

问题是它在 运行 秒后停止安排(每次 运行 秒的数量不同)。让我们来看看 Spring 批处理模式:

select ex.job_instance_id, ex.create_time, ex.start_time, ex.end_time, ex.status, ex.exit_code, ex.exit_message
from batch_job_execution ex inner join batch_job_instance bji on ex.job_instance_id = bji.job_instance_id
order by start_time desc, job_instance_id desc;

然后沉默。日志中没有什么特别的。 我认为唯一有意义的是在该实例上还有两个作业 运行ning。其中之一非常耗时,因为它通过 SMTP 发送电子邮件。 整个工作时间表是:

job:
  invitation-email: "0 0/10 * * * *"
  assignment-rules: "0 0/5  * * * *"
  rm-subordinates-count: "0 0/30 * * * *"

同事们,谁能指出我解决这个问题的方法?

非常感谢

使用默认 SyncTaskExecutor 启动作业在您的用例中并不安全,因为所有作业都将由单个线程执行。如果其中一项工作需要超过 5 分钟才能完成 运行,下一个工作将堆积起来并且在某个时候无法启动。

我会在您的用例中配置一个带有异步 TaskExecutor 实现(如 org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor)的 JobLauncher。您可以在 Configuring a JobLauncher 部分找到示例(参见 "Figure 3. Asynchronous Job Launcher Sequence")。

除了 Spring 批处理的 JobLauncher 使用的任务执行器配置之外,您还需要确保 Spring 使用正确的任务执行器启动计划任务(因为您使用的是 @EnableScheduling)。详情请参阅Task Execution and Scheduling部分。