Способ остановки задания Spring Batch

Оглавление

введение

обзор

нуждаться

Решение 1. Метод пошагового слушателя

Сценарий 2: Метка остановки StepExecution

Перейти к видео версии


введение

Продолжайте читать предыдущую статью: Методы запуска заданий Spring Batch . После понимания методов запуска заданий Spring Batch давайте узнаем о  методах запуска заданий Spring Batch и методах остановки заданий. Вот три основных метода.

обзор

Возможны 3 ситуации остановки задания:

  • естественный конец

    Задание успешно выполнено и нормально остановлено. В настоящее время состояние возврата задания: ЗАВЕРШЕНО.

  • Процесс выполнения нештатного завершения задания останавливается из-за различных неожиданных прерываний задания, и большинство заданий возвращают статус: FAILED.

  • конец программирования

Результат обработки данных на определенном шаге не соответствует предпосылкам для выполнения следующего шага. Остановить его вручную. Как правило, статус возврата устанавливается в: ОСТАНОВЛЕНО

Приведенные выше 1 и 2 случаи относительно просты, давайте сосредоточимся на третьем: остановить задание программно.

нуждаться

Моделирование рабочего сценария

1> Есть класс ресурсов, который имеет 2 атрибута: total: totalCount = 100, read count: readCount = 0

2> Шаги дизайна 2, шаг 1 используется для наложения readCount для имитации чтения ресурсов из базы данных, шаг 2 используется для выполнения логики

3> Когда totalCount == readCount, это нормальная ситуация и нормально заканчивается. Если нет, то это ненормальное состояние. В это время шаг 2 не выполняется, и задание останавливается напрямую.

4> Восстановите данные, начните выполнение с шага 1 и завершите работу.

public class ResouceCount {
    public static int totalCount = 100;  //总数
    public static int  readCount = 0;    //读取数
}

Существует два способа достижения вышеуказанных требований.

Решение 1. Метод пошагового слушателя

слушатель

public class StopStepListener implements StepExecutionListener {
    @Override
    public void beforeStep(StepExecution stepExecution) {
    }

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {

       //不满足
        if(ResouceCount.totalCount != ResouceCount.readCount){
            return ExitStatus.STOPPED;  //手动停止,后续可以重启
        }
        return stepExecution.getExitStatus();
    }
}

код

package com.langfeiyes.batch._16_job_stop;

import com.langfeiyes.batch._01_hello.HelloJob;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableBatchProcessing
public class ListenerJobStopJob {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    private int readCount = 50; //模拟只读取50个
    @Bean
    public Tasklet tasklet1(){
        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                for (int i = 1; i <= readCount; i++) {
                    System.out.println("---------------step1执行-"+i+"------------------");
                    ResouceCount.readCount ++;
                }
                return RepeatStatus.FINISHED;
            }
        };
    }

    @Bean
    public Tasklet tasklet2(){
        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                System.err.println("step2执行了.......");
                System.err.println("readCount:" + ResouceCount.readCount + ", totalCount:" + ResouceCount.totalCount);
                return RepeatStatus.FINISHED;
            }
        };
    }

    @Bean
    public StopStepListener stopStepListener(){
        return new StopStepListener();
    }
    @Bean
    public Step step1(){
        return stepBuilderFactory.get("step1")
                .tasklet(tasklet1())
                .listener(stopStepListener())
                .allowStartIfComplete(true)  //执行完后,运行重启
                .build();
    }

    @Bean
    public Step step2(){
        return stepBuilderFactory.get("step2")
                .tasklet(tasklet2())
                .build();
    }

    //定义作业
    @Bean
    public Job job(){
        return jobBuilderFactory.get("job-stop-job")
                .start(step1())
                .on("STOPPED").stopAndRestart(step1())
                .from(step1()).on("*").to(step2()).end()
                .build();

    }
    public static void main(String[] args) {
        SpringApplication.run(ListenerJobStopJob.class, args);
    }
}

Первое выполнение: readCount в tasklet1 по умолчанию выполняется 50 раз, и условие не выполняется . )) разветвление, остановка и разрешение перезапуска - - При следующем перезапуске начните с шага 1

Второе выполнение, измените readCount = 100, запустите задание снова, задача 1 проходит 100 раз, удовлетворяет условиям, stopStepListener() afterStep нормально возвращается, и управление условием задания идет.from ( step1()).on("*") .to(step2()).end() ветвь, завершается нормально.

Примечание: В методе step1() необходимо добавить код .allowStartIfComplete(true), так как первое выполнение шага step1 не соответствует условиям, но все же относится к нормальному концу (процесс tasklet1 выполняется нормально ) , код состояния: COMPLETED, the first Для второго перезапуска шаг 1, который завершается нормально, по умолчанию не может быть выполнен, поэтому он должен быть установлен: .allowStartIfComplete(true) разрешает перезапуск шага 1, даже если он завершен.

Сценарий 2: Метка остановки StepExecution

package com.langfeiyes.batch._17_job_stop_sign;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableBatchProcessing
public class SignJobStopJob {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    private int readCount = 50; //模拟只读取50个
    @Bean
    public Tasklet tasklet1(){
        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                for (int i = 1; i <= readCount; i++) {
                    System.out.println("---------------step1执行-"+i+"------------------");
                    ResouceCount.readCount ++;
                }

                if(ResouceCount.readCount != ResouceCount.totalCount){
                    chunkContext.getStepContext().getStepExecution().setTerminateOnly();
                }

                return RepeatStatus.FINISHED;
            }
        };
    }

    @Bean
    public Tasklet tasklet2(){
        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                System.err.println("step2执行了.......");
                System.err.println("readCount:" + ResouceCount.readCount + ", totalCount:" + ResouceCount.totalCount);
                return RepeatStatus.FINISHED;
            }
        };
    }


    @Bean
    public Step step1(){
        return stepBuilderFactory.get("step1")
                .tasklet(tasklet1())
                .allowStartIfComplete(true)
                .build();
    }

    @Bean
    public Step step2(){
        return stepBuilderFactory.get("step2")
                .tasklet(tasklet2())
                .build();
    }

    //定义作业
    @Bean
    public Job job(){
         return jobBuilderFactory.get("job-stop-job")
                .start(step1())
                //.on("STOPPED").stopAndRestart(step1())
                //.from(step1()).on("*").to(step2()).end()
                .next(step2())
                .build();

    }
    public static void main(String[] args) {
        SpringApplication.run(SignJobStopJob.class, args);
    }
}

Есть 2 измененных кода

task1(), ниже есть еще решения

if(ResouceCount.readCount != ResouceCount.totalCount){
    chunkContext.getStepContext().getStepExecution().setTerminateOnly();
}

Среди них StepExecution#setTerminateOnly() устанавливает отметку остановки для запущенного stepExecution, а Spring Batch сразу останавливает шаг после распознавания, а затем останавливает процесс.

работа () изменяется

return jobBuilderFactory.get("job-stop-job")
    .start(step1())
    .next(step2())
    .build();

Последовательность стандартных шагов настройки.

На этом эта статья закончена. Если вы хотите знать, что будет дальше, пожалуйста, прослушайте следующую главу, чтобы разбить ее на части~

Перейти к видео версии

Если вас не устраивает чтение текста, вы можете переключиться на видеоверсию:

Supongo que te gusta

Origin blog.csdn.net/langfeiyes/article/details/128906739
Recomendado
Clasificación