[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.또한 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 가지 해결책이 있습니다.
먼저 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);
from https://stackoverflow.com/questions/33948102/partitioned-job-cant-stop-by-itself-after-finishing-spring-batch by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] MockMvc를 통해 모든 요청에 대해 서블릿 경로를 설정하는 방법 (0) | 2019.04.11 |
---|---|
[SPRING] Spring Ldap 인증 사용 방법 (0) | 2019.04.11 |
[SPRING] 엔티티를 json으로 최대 절전 모드로 전환 (0) | 2019.04.11 |
[SPRING] Spring Hibernate SessionFactory (0) | 2019.04.11 |
[SPRING] 간단한 봄, 독립 실행 형 응용 프로그램에 대한 ClasspathApplicationContext 사용, 재사용 방법 (0) | 2019.04.11 |