首页 文章

Spring-boot - 如何按计划重新启动作业

提问于
浏览
1

我正在使用spring-batch-2.2.5开发一个spring-boot应用程序 . - 一个简单的应用程序 - 从db读取项目并写入文件 . 运行应用程序时遇到两个问题:

  • 作业运行良好一次,但第二次(经过60秒的固定延迟后)似乎运行,但表示步骤状态为已完成 .

  • 第二个问题,是我随机获取WriterNotOpenException:Writer必须先打开才能写入 . 这在第一次运行时发生 . 已写入一些项目,但随后发生异常 .

在org.springframework.batch.item.file.FlatFileItemWriter.write(FlatFileItemWriter.java:255)〜[spring-batch-infrastructure-2.2.5.RELEASE.jar:na] org.springframework.batch.core.step . item.SimpleChunkProcessor.writeItems(SimpleChunkProcessor.java:175)〜[spring-batch-core-2.2.5.RELEASE.jar:na] at org.springframework.batch.core.step.item.SimpleChunkProcessor.doWrite(SimpleChunkProcessor.java) :151)〜[spring-batch-core-2.2.5.RELEASE.jar:na] org.springframework.batch.core.step.item.SimpleChunkProcessor.write(SimpleChunkProcessor.java:274)〜[spring-batch-核 - 2.2.5.RELEASE.jar:NA]

我确保JobParameters为每次运行都有一个新的时间戳,但这似乎没有帮助 .

这是代码:

public ItemReader<DomainClass> reader() {
    ArrayList<DomainClass> records = service.findrecords()
    return new IteratorItemReader<DomainClass>(records)
}

@Bean
public ItemProcessor<DomainClass, DomainClass> processor() {
    return new MyItemProcessor()
}

@Bean
public FlatFileItemWriter<DomainClass> writer() {
    FlatFileItemWriter flatFileItemWriter = new FlatFileItemWriter()
        DelimitedLineAggregator t = new DelimitedLineAggregator(delimiter: ',')
            t.setFieldExtractor(new BeanWrapperFieldExtractor(names: ["id", "description", "type", "date"]))
        flatFileItemWriter.setLineAggregator(t)
        flatFileItemWriter.setResource(new FileSystemResource('output.txt'))
    return flatFileItemWriter
}

@Bean
public Job  myJob(JobBuilderFactory jobs, Step s1) {
    Job job = jobs.get("myJob")
        .incrementer(new RunIdIncrementer())
        .flow(s1).end().
        .build()

    return job
}

@Bean
public Step step1(StepBuilderFactory stepBuilderFactory, ItemReader<DomainClass> reader,
                                    ItemWriter<DomainClass> writer, ItemProcessor<DomainClass, DomainClass> processor) {
    logger.info "creating step1"
    return stepBuilderFactory.get("step1")
        .<DomainClass, DomainClass> chunk(10)
        .reader(reader)
        .processor(processor)
        .writer(writer)
        .build();
}

这是第二次尝试的状态:没有错误,但步骤说完了 . 我不知道如何在上面的代码中将作业设置为“可重启” .

INFO  com.myapp.MyJobsApplication - Running MyJobs...
INFO  o.s.b.c.l.support.SimpleJobLauncher - Job: [FlowJob: [name=myJob]] launched with the following parameters: [{time=1397603933056}]
INFO  o.s.batch.core.job.SimpleStepHandler - Executing step: [step1]
INFO  o.s.b.c.l.support.SimpleJobLauncher - Job: [FlowJob: [name=myJob]] completed with the following parameters: [{time=1397603933056}] and the following status: [COMPLETED]

看看spring boot启动跟踪,似乎有两个线程试图启动(main和pool-3-thread-1)..不确定这是否也是一个问题:

18:17:46.441 [pool-3-thread-1] INFO  o.s.b.c.l.support.SimpleJobLauncher - Job: [FlowJob: [name=myJob]] launched with the following parameters: [{time=1397603866386}]
18:17:46.463 [main] INFO  o.s.b.c.l.support.SimpleJobLauncher - Job: [FlowJob: [name=myJob]] launched with the following parameters: [{run.id=2}]

1 回答

  • 2

    那可能是3个问题,所以它可能有助于分解它 . 我可以在这里回答你的问题以节省评论空间......

    • 你在2个线程中有2个执行,因为一个来自 @Scheduled 执行(我猜是通过线程ID),一个是来自Spring Boot中实现的"launch a single job on startup"规则(你可以关闭它 - 参见docs,例如set "spring.batch.job.enabled=false") .

    • 你似乎对第二次执行成功完成感到惊讶,但你没有说明原因 . 那是问题吗?

    • 如果您的进程将要执行并发作业(看起来可能是这样),您应该创建有状态组件 @StepScope . 根据异常,项目编写者看起来是一个很好的候选人 .

相关问题