복붙노트

[SPRING] 분할 된 작업은 완료 후에 자체적으로 멈출 수 없습니까? 봄 배치

SPRING

분할 된 작업은 완료 후에 자체적으로 멈출 수 없습니까? 봄 배치

저는 두 단계의 작업 중 하나를 파티셔닝 단계로 작성했습니다. 파티션 단계에서는 TaskExecutorPartitionHandler를 사용하고 스레드에서 5 개의 슬레이브 단계를 실행합니다. 작업은 main () 메소드에서 시작됩니다. 그러나 모든 슬레이브 ItemReader가 null을 반환 한 후에 멈추지 않습니다 .- 마침표. 그리고 프로그램이 main () 메소드 (System.out.println ( "Finished"))의 마지막 코드 행을 지나치더라도 프로그램 프로세스는 멈추지 않고 메모리에 매달려 아무것도하지 않습니다. 프로그램을 멈추기 위해서는 이클립스 패널의 멈춤 버튼을 눌러야한다.

다음은 JobLauncher.run ()에 의해 반환 된 JobExecution의 내용으로, Job 실행의 성공적인 상태를 알립니다.

성공적인 Job 실행을 가진 Spring Batch 프로그램이 여전히 정지되는 이유는 무엇입니까? 저를 어디에서 일할 지 가르쳐주십시오. Spring Batch가 관리하는 멀티 스레딩 부분이 멈추지 않는다고 생각합니다.

간단한 작업 실행 코드

        Job job = (Job) context.getBean("jobPages");
        try {
            JobParameters p=new JobParametersBuilder()
                .toJobParameters();

            JobExecution result = launcher.run(job, new JobParameters());

            System.out.println(result.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        context.getBean("idSet");
        AtomicInteger n=(AtomicInteger) context.getBean("pageCount");
        System.out.println(n.get());        
        System.out.println("Finished");

청원 자 및 PatitionHandler 구성

    @Bean @Autowired 
    public PartitionHandler beanPartitionHandler(
        TaskExecutor beanTaskExecutor, 
        @Qualifier("beanStepSlave") Step beanStepSlave
        ) throws Exception
    {
        TaskExecutorPartitionHandler h=new TaskExecutorPartitionHandler();
        h.setGridSize(5);
        h.setTaskExecutor(beanTaskExecutor);
        h.setStep(beanStepSlave);   
        h.afterPropertiesSet(); 
        return h;
    }
    @Bean public TaskExecutor beanTaskExecutor() {
        ThreadPoolTaskExecutor e = new ThreadPoolTaskExecutor();
        e.setMaxPoolSize(5);
        e.setCorePoolSize(5);
        e.afterPropertiesSet();
        return e;
    }

유일한 단계와 그것의 노예 단계

@Bean public Step beanStepMaster(
        Step beanStepSlave,
        Partitioner beanPartitioner,
        PartitionHandler beanPartitionHandler
        )   throws Exception 
    {
        return stepBuilderFactory().get("stepMaster")
        .partitioner(beanStepSlave)
        .partitioner("stepSlave", beanPartitioner)
        .partitionHandler(partitionHandler)
        .build();
    }
    @Bean @Autowired 
    public Step beanStepSlave(
        ItemReader<String> beanReaderTest,
        ItemProcessor<String, String> beanProcessorTest,
        ItemWriter<String> beanWriterTest) throws Exception{
        return stepBuilderFactory().get("stepSlave")
            .<String, String>chunk(1)
            .reader(beanReaderTest)
            .processor(beanProcessorTest)
            .writer(beanWriterTest)
            .build();
    }

우리는

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>RELEASE</version>
      <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.2.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>4.2.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.batch</groupId>
        <artifactId>spring-batch-core</artifactId>
        <version>RELEASE</version>      
    </dependency>
    <dependency>
        <groupId>org.springframework.retry</groupId>
        <artifactId>spring-retry</artifactId>
        <version>1.1.2.RELEASE</version>
    </dependency>

<dependency>    
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>RELEASE</version>
</dependency>

해결법

  1. ==============================

    1.또한 ThreadPoolTaskExecutor를 사용할 때 완성 된 상태에서 파티셔닝 된 Spring 배치 애플리케이션에 어려움이있었습니다. 또한 집행자가 모든 파티션의 작업을 완료하지 못하게하는 것을 보았습니다.

    또한 ThreadPoolTaskExecutor를 사용할 때 완성 된 상태에서 파티셔닝 된 Spring 배치 애플리케이션에 어려움이있었습니다. 또한 집행자가 모든 파티션의 작업을 완료하지 못하게하는 것을 보았습니다.

    나는 그 문제를 해결하는 두 가지 방법을 발견했다.

    첫 번째 해결 방법은 ThreadPoolTaskExecutor 대신 SimpleAsyncTaskExecutor를 사용하는 것입니다. 스레드를 다시 만드는 데 추가 오버 헤드가 발생하지 않는다면 간단합니다.

    두 번째 솔루션은 ThreadPoolTaskExecutor에서 shutdown을 호출하는 JobExecutionListener를 만드는 것입니다.

    다음과 같이 JobExecutionListener를 만들었습니다.

    @Bean
    public JobExecutionListener jobExecutionListener(ThreadPoolTaskExecutor executor) {
        return new JobExecutionListener() {
            private ThreadPoolTaskExecutor taskExecutor = executor;
            @Override
            public void beforeJob(JobExecution jobExecution) {
    
            }
    
            @Override
            public void afterJob(JobExecution jobExecution) {
                taskExecutor.shutdown();
            }
        };
    }
    

    다음과 같이 내 작업 정의에 추가했습니다.

    @Bean
    public Job partitionedJob(){
        return jobBuilders.get("partitionedJob")
                .listener(jobExecutionListener(taskExecutor()))
                .start(partitionedStep())
                .build();
    }
    
  2. ==============================

    2.그 원인을 알지 못하더라도 문제에 대한 2 가지 해결책이 있습니다.

    그 원인을 알지 못하더라도 문제에 대한 2 가지 해결책이 있습니다.

    먼저 CommandLineJobRunner를 사용하여 작업을 시작할 수 있습니다. 여기 문서를 참조하십시오. 이 클래스는 작업이 끝나면 자동으로 프로그램을 종료하고 ExitStatus를 반환 코드 (COMPLETED = 0, FAILED = 1 ...)로 변환합니다. 기본 반환 코드는 SimpleJvmExitCodeMapper에 의해 제공됩니다.

    두 번째 해결책은 JobLauncher.run () 다음에 수동으로 System.exit () 명령을 호출하는 것입니다. 작업의 ExitStatus를 수동으로 변환하여 수동 종료에서 사용할 수도 있습니다.

    // Create Job
    JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
    Job job = (Job) context.getBean(jobName);
    
    // Create return codes mapper
    SimpleJvmExitCodeMapper mapper = new SimpleJvmExitCodeMapper();
    
    // Start Job
    JobExecution execution = jobLauncher.run(job, new JobParameters());
    
    // Close context
    context.close();
    
    // Map codes and exit
    String status = execution.getExitStatus().getExitCode();
    Integer returnCode = mapper.intValue(status);
    System.exit(returnCode);
    
  3. from https://stackoverflow.com/questions/33948102/partitioned-job-cant-stop-by-itself-after-finishing-spring-batch by cc-by-sa and MIT license