Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot Spring批处理作业调度器在多次运行后停止执行_Spring Boot_Spring Batch_Scheduler - Fatal编程技术网

Spring boot Spring批处理作业调度器在多次运行后停止执行

Spring boot Spring批处理作业调度器在多次运行后停止执行,spring-boot,spring-batch,scheduler,Spring Boot,Spring Batch,Scheduler,在一个项目中,我们必须运行一个定期启动的作业(现在QA env上每5分钟一次),为40k用户处理一些任务。 我们决定使用Spring批处理,因为它非常适合并使用几乎默认的配置实现它(例如,它在引擎盖下使用SyncTaskExecutor)。 好的,有一个作业由一个步骤组成: 开箱即用HibernatePagingItemReader 在内存中执行轻量级计算的自定义ItemProcessor 自定义ItemWriter,通过几个JPQL和本机查询将数据持久化到同一个PostgreSQL数据库 作业

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

  • 开箱即用
    HibernatePagingItemReader
  • 在内存中执行轻量级计算的自定义
    ItemProcessor
  • 自定义
    ItemWriter
    ,通过几个JPQL和本机查询将数据持久化到同一个PostgreSQL数据库
  • 作业本身通过
    @EnableScheduling
    进行调度,并且每5分钟由cron expression触发一次:

    @Scheduled(cron=“${job.assignment rules}”)
    void processAssignments(){
    试一试{
    调试(“正在运行分配处理作业”);
    运行(assignmentProcessingJob,populateJobParameters());
    }捕获(作业执行异常e){
    日志错误(“作业处理失败”,e);
    }
    }
    
    下面是
    application.yml
    中的cron表达式:

    job:
      assignment-rules: "0 0/5  * * * *"
    
    问题在于,在多次运行(每次运行的次数不同)后,它将停止计划。让我们来看看Spring批处理模式:

    选择ex.job\u instance\u id、ex.create\u time、ex.start\u time、ex.end\u time、ex.status、ex.exit\u code、ex.exit\u message
    从批处理作业执行ex内部联接批处理作业实例bji on ex.job\u instance\u id=bji.job\u instance\u id
    按开始时间描述、作业实例描述、id描述排序;
    
    然后是沉默。原木没有什么特别的。 我认为唯一有意义的是,在该实例上还有两个作业在运行。其中一个很耗时,因为它通过SMTP发送电子邮件。 整个作业计划是:

    job:
      invitation-email: "0 0/10 * * * *"
      assignment-rules: "0 0/5  * * * *"
      rm-subordinates-count: "0 0/30 * * * *"
    
    各位同事,有谁能告诉我解决这个问题的方法吗


    非常感谢您使用默认的
    SyncTaskExecutor
    启动作业在您的用例中并不安全,因为所有作业都将由单个线程执行。如果其中一个作业的运行时间超过5分钟,则下一个作业将堆积起来,无法在某个点启动

    我会在您的用例中配置一个带有异步
    TaskExecutor
    实现的
    JobLauncher
    (比如
    org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
    )。您可以在本节中找到一个示例(请参见“图3.异步作业启动程序序列”)


    除了配置为Spring Batch的
    JobLauncher
    使用的任务执行器之外,您还需要确保Spring Boot使用了正确的任务执行器来调度任务(因为您使用的是
    @EnableScheduling
    )。有关更多详细信息,请参阅本节。

    我认为原因可能是spring批处理或计划程序未配置,但同样,两者都是“默认值”。似乎
    SyncTaskExecutor
    是同步的,但它丢失了自以来计划的作业。如果您可以记录
    线程
    ,这将是一件非常棒的事情,默认情况下
    线程队列
    很小,如果您自定义它可能会工作的话。“试试看!”乔纳桑霍克斯,这正是我整个上午一直在思考的问题。是的,看起来SMTP发送者持有该线程。我会尝试将其移动到单独的线程池,并且一定会让我知道这是否是原因,让我知道@IgorPetrov@JonathanJohx对不起,忘了联系你了。您是对的,问题出在同一个
    SyncTaskExecutor
    调度的另一个长时间运行的任务中。将调度程序拆分为不同的线程解决了这个问题。谢谢