스프링 배치 스케줄러 | 스프링 부트의 스프링 배치 | Csv를 데이터베이스로 | 기술 입문서 답을 믿으세요

당신은 주제를 찾고 있습니까 “스프링 배치 스케줄러 – 스프링 부트의 스프링 배치 | CSV를 데이터베이스로 | 기술 입문서“? 다음 카테고리의 웹사이트 you.maxfit.vn 에서 귀하의 모든 질문에 답변해 드립니다: you.maxfit.vn/blog. 바로 아래에서 답을 찾을 수 있습니다. 작성자 Tech Primers 이(가) 작성한 기사에는 조회수 219,280회 및 좋아요 3,185개 개의 좋아요가 있습니다.

스프링 배치 스케줄러 주제에 대한 동영상 보기

여기에서 이 주제에 대한 비디오를 시청하십시오. 주의 깊게 살펴보고 읽고 있는 내용에 대한 피드백을 제공하세요!

d여기에서 스프링 부트의 스프링 배치 | CSV를 데이터베이스로 | 기술 입문서 – 스프링 배치 스케줄러 주제에 대한 세부정보를 참조하세요

This video covers the Spring Boot with Spring Batch example for loading CSV into Database.
🔗Github Code: https://github.com/TechPrimers/spring-batch-example-1
📌 Related Playlist
================
🔗Spring Boot Primer – https://www.youtube.com/playlist?list=PLTyWtrsGknYegrUmDZB6rcqMotOFZKvbn
🔗Spring Cloud Primer – https://www.youtube.com/playlist?list=PLTyWtrsGknYeOJHtd3Ll93GRf28hrjlHV
🔗Spring Microservices Primer – https://www.youtube.com/playlist?list=PLTyWtrsGknYdZlO7LAZFEElWkEk59Y2ak
🔗Spring JPA Primer – https://www.youtube.com/playlist?list=PLTyWtrsGknYdt079e1pyvpgLrJ48RQ1LK
🔗Java 8 Streams – https://www.youtube.com/playlist?list=PLTyWtrsGknYdqY_7lwcbJ1z4bvc5yEEZl
🔗Spring Security Primer – https://www.youtube.com/playlist?list=PLTyWtrsGknYe0Sba9o-JRtnRlkl4gXMQl
🔗Containers Primer – https://www.youtube.com/playlist?list=PLTyWtrsGknYf_Oee7YOvom5Ev0F3-E2zB
🔗Kubernetes Primer – https://www.youtube.com/playlist?list=PLTyWtrsGknYfanKF33E12LdJvl5q5PZGp
🔗AWS Primer – https://www.youtube.com/playlist?list=PLTyWtrsGknYdyi0JR7c1wsuv-Plrwrzqj
💥Join TechPrimers Slack Community: https://bit.ly/JoinTechPrimers
💥Telegram: https://t.me/TechPrimers
💥TechPrimer HindSight (Blog): https://medium.com/TechPrimers
💥Website: http://techprimers.com
💥Slack Community: https://techprimers.slack.com
💥Twitter: https://twitter.com/TechPrimers
💥Facebook: http://fb.me/TechPrimers
💥GitHub: https://github.com/TechPrimers or https://techprimers.github.io/
🎬Video Editing: iMovie
🎼Background Music:
Dyalla
Joakin Karud
—————————————————————
🔥 Disclaimer/Policy:
The content/views/opinions posted here are solely mine and the code samples created by me are open sourced.
You are free to use the code samples in Github after forking and you can modify it for your own use.
All the videos posted here are copyrighted. You cannot re-distribute videos on this channel in other channels or platforms.
#Spring #SpringBatch #TechPrimers

스프링 배치 스케줄러 주제에 대한 자세한 내용은 여기를 참조하세요.

Spring batch+Scheduler 구현 해보기

Spring batch+Scheduler 구현 해보기. Tasklet 으로 Spring Batch, 날로 먹기. 명수옹. 주기적으로 처리해줘야 할 일이 있다면? 선배님 : 결제 …

+ 자세한 내용은 여기를 클릭하십시오

Source: dalgun.dev

Date Published: 8/3/2022

View: 6954

[스프링] batch + scheduler로 주기적인 파일 삭제 구현

Spring에서 batch 와 scheduler를 사용하여 매일 같은시각에 업데이트된 시각이 일주일 이전인 파일을 서버와 DB에서 삭제하는 기능을 구현하였다.

+ 여기에 표시

Source: gimmesome.tistory.com

Date Published: 3/30/2022

View: 825

Spring Batch와 Scheduler – SMU개발자

1. 스프링 배치 특정한 시간에 내가 원하는 일을 자동으로 시키는게 스케줄러의 역할이고 처음에 이것에 대해 먼저 학습을 하여 스프링 배치에 대한 …

+ 여기에 더 보기

Source: smujihoon.tistory.com

Date Published: 1/24/2022

View: 3785

Spring Batch initializr / 스케쥴러 만들기 – velog

What You Need About 15 minutes JDK 1.8 or later / Gradle 4+ or Maven 3.2+IDE: Spring Tool Suite (STS) /IntelliJ IDEA 이전 프로젝트에서 …

+ 더 읽기

Source: velog.io

Date Published: 6/6/2021

View: 3006

Spring으로 배치 만들기 (quartz, scheduler,task) – Dev. MG

스프링에는 일괄 처리(batch processing) 배치를 만드는 여러가지의 기능이 있다. 방법1. quartz 스케줄링 객체 사용. 방법2. 설정 …

+ 여기에 보기

Source: devmg.tistory.com

Date Published: 2/24/2022

View: 6229

How to Trigger and Stop a Scheduled Spring Batch Job

Firstly, we have a SpringBatchScheduler to configure scheduling and batch job. A method launchJob() will be registered as a scheduled task …

+ 여기에 표시

Source: www.baeldung.com

Date Published: 8/10/2022

View: 599

Spring Boot Batch Job + Scheduler Simple Example – JavaInUse

In this post we develop a simple Spring Boot Batch application where batch job gets triggered using a scheduler. Conser the simple use case where the user …

+ 자세한 내용은 여기를 클릭하십시오

Source: www.javainuse.com

Date Published: 7/18/2022

View: 9579

[SPRING] 스프링 배치에서 사용되는 Quartz 배치 스케줄링

쿼츠(Quartz) · 1. 스케줄러(Scheduler) · 2. 잡(Job) · 3. 트리거(Trigger).

+ 더 읽기

Source: prodo-developer.tistory.com

Date Published: 3/16/2022

View: 1714

Spring 배치, 스케쥴러 사용하기 : Quartz, @Scheduled – 티스토리

Spring 배치, 스케쥴러 사용하기 : Quartz, @Scheduled. ojava 2018. 10. 30. 18:33. 반응형. Spring 배치, 스케쥴러 사용하기 : Quartz, @Scheduled.

+ 여기에 보기

Source: ojava.tistory.com

Date Published: 6/12/2022

View: 2103

주제와 관련된 이미지 스프링 배치 스케줄러

주제와 관련된 더 많은 사진을 참조하십시오 스프링 부트의 스프링 배치 | CSV를 데이터베이스로 | 기술 입문서. 댓글에서 더 많은 관련 이미지를 보거나 필요한 경우 더 많은 관련 기사를 볼 수 있습니다.

스프링 부트의 스프링 배치 | CSV를 데이터베이스로 | 기술 입문서
스프링 부트의 스프링 배치 | CSV를 데이터베이스로 | 기술 입문서

주제에 대한 기사 평가 스프링 배치 스케줄러

  • Author: Tech Primers
  • Views: 조회수 219,280회
  • Likes: 좋아요 3,185개
  • Date Published: 2018. 6. 15.
  • Video Url link: https://www.youtube.com/watch?v=1XEX-u12i0A

Spring batch+Scheduler 구현 해보기

Spring batch+Scheduler 구현 해보기 Tasklet 으로 Spring Batch, 날로 먹기

주기적으로 처리해줘야 할 일이 있다면?

선배님 : 결제 승인 이후에 승인내역을 특정 VAN 사로 전송해줘야 하는 이슈 가 있다.

달군 : 헐, 실패하면요?

선배님 : 재시도 해야지, (너가 할꺼지, 달군아?)

달군 : (반짝반짝) 그럼 일단 실패한건 재시도 테이블에 넣고 주기적으로 bulk 로 읽어와서, 재전송하고, 결과를 정리할께요!

( 블로그의 첫 도입부는 항상 어렵다 ㅠㅠ )

그래서 선택한것이,

Spring Batch + Scheduler

Spring Batch 공식문서 를 읽어보면, 이해는 잘 되지만 어떻게 적용해야할지 난감했다.

기본적인 구조

배치 하나가 하나의 Job 이며, 여러개의 Step 이 모여 Job 을 이루게 된다. 다만, Step 은 Reader , Processor, Writer 가 Tasklet 로 대체 될 수 있는데 이것은 하나의 큰 덩어리로 나의 경우 굳이 3분류로 나누지 않고 각 스텝별로 Tasklet 단위로 작성을 하는게 기능 별로 정의하는 느낌이라 편했다.

(맞게 쓰는건지는 모르겠어서, 날로 먹..)

Reader + Processor + Writer = Tasklet

자 그러면, 내 상황에 맞게 코딩을 해보자!

이중화 구조를 감안하여 Lock Table 조회하여 다른 Instance가 사용중인지 확인하기

@Bean public Step step1 (){ return stepBuilderFactory . get ( “step1” ) . tasklet (( stepContribution , chunkContext ) -> { log . debug ( “======= 전송 배치 시작 =======” ); LockTable lockTable = Optional . ofNullable ( lockTableRepository . findOne ( “play-batch” )) . orElse ( LockTable . builder () . instanceId ( instanceId ) . useYn ( false ) . checkDataTime ( LocalDateTime . now ()) . build ()); log . debug ( “======= Lock Table 사용 여부:{},” , lockTable . isUseYn ()); if ( lockTable . isUseYn ()){ log . debug ( “======= Table 사용 중으로 종료 ” ); stepContribution . setExitStatus ( ExitStatus . FAILED ); } else { lockTable . setUseYn ( true ); lockTableRepository . save ( lockTable ); } return RepeatStatus . FINISHED ; }). build (); }

처리할 아이템이 있는지 확인하기

@Bean public Step step2 (){ return stepBuilderFactory . get ( “step2” ) . tasklet (( stepContribution , chunkContext ) -> { int itemCnt = payInfoRepository . countAllBySuccessYn ( false ); log . debug ( “======= 처리할 Item 개수 : {}” , itemCnt ); if ( 0 == itemCnt ){ log . debug ( “======= 처리할 Item 이 없어 종료 ” ); LockTable lockTable = lockTableRepository . findOne ( instanceId ); lockTable . setUseYn ( false ); lockTable . setCheckDataTime ( LocalDateTime . now ()); stepContribution . setExitStatus ( ExitStatus . FAILED ); } return RepeatStatus . FINISHED ; }). build (); }

성공한 아이템의 후처리 @Bean public Step step3 (){ return stepBuilderFactory . get ( “step3” ) . tasklet (( stepContribution , chunkContext ) -> { List < PayInfo > payInfoList = payInfoRepository . findAllBySuccessYn ( false ); for ( PayInfo payInfo: payInfoList ){ // 무언가를 처리하고 결과값이 TRUE 일때 결과 성공 처리 if ( true ){ payInfo . setRequestDateTime ( LocalDateTime . now ()); payInfo . setSuccessYn ( true ); payInfoRepository . save ( payInfo ); } } return RepeatStatus . FINISHED ; }). build (); }

Lock Table 초기화 후 종료처리

@Bean public Step step4 (){ return stepBuilderFactory . get ( “step4” ) . tasklet (( stepContribution , chunkContext ) -> { LockTable lockTable = lockTableRepository . findOne ( instanceId ); lockTable . setUseYn ( false ); lockTable . setCheckDataTime ( LocalDateTime . now ()); lockTableRepository . save ( lockTable ); log . debug ( “======= 전송 배치 종료 =======” ); return RepeatStatus . FINISHED ; }). build (); }

이것들을 조합하여 하나의 Job 으로 엮어보면 다음과 같다.

@Bean public Job job (){ return jobBuilderFactory . get ( “job” ) . start ( step1 ()) //STEP 1 실행 . on ( “FAILED” ) // STEP 1 결과가 FAILED 일 경우 . end () // 종료 . from ( step1 ()) // STEP1 의 결과로부터 . on ( “*” ) // FAILED 를 제외한 모든 경우 . to ( step2 ()) // STEP 2로 이동 후 실행 . on ( “FAILED” ) // STEP 2의 결과가 FAILED 일 경우 . end () // 종료 . from ( step2 ()) // STEP2 의 결과로부터 . on ( “*” ) // FAILED 를 제외한 모든 경우 . to ( step3 ()) // STEP 3로 이동 후 실행 . next ( step4 ()) // STEP 3의 결과에 상관없이 STEP 4 실행 . on ( “*” ) // STEP4 의 모든 결과에 상관없이 . end () // FLOW 종료 . end () // JOB 종료 . build (); }

이렇게 하나의 Job이 생성이 되었고 이것을 이제 Scheduler 에 등록하여 주기적으로 실행되게 적용하였다.

@Slf4j @Component public class JobScheduler { @Autowired private JobLauncher jobLauncher ; @Autowired private JobConfiguration jobConfiguration ; @Scheduled ( initialDelay = 10000 , fixedDelay = 30000 ) public void runJob () { Map < String , JobParameter > confMap = new HashMap <>(); confMap . put ( “time” , new JobParameter ( System . currentTimeMillis ())); JobParameters jobParameters = new JobParameters ( confMap ); try { jobLauncher . run ( jobConfiguration . job (), jobParameters ); } catch ( JobExecutionAlreadyRunningException | JobInstanceAlreadyCompleteException | JobParametersInvalidException | org . springframework . batch . core . repository . JobRestartException e ) { log . error ( e . getMessage ()); } } }

블로그에 있는 모든 소스는 여기서 확인할 수 있어요

결론

Spring Boot의 Batch 는 개발자가 비지니스 로직에만 집중할 수 있도록 자동화가 잘 되어있다(날로 먹었).

item reader, processor, writer 로 짜보려다 일주일 날린거는 안비밀

Please enable JavaScript to view the comments powered by Disqus.

[스프링] batch + scheduler로 주기적인 파일 삭제 구현

batch 란?

배치작업은 데이터를 실시간으로 처리하는게 아니라, 일괄적으로 모아서 한번에 처리하는 작업을 의미한다. 가령, 은행의 정산작업의 경우 배치 작업을 통해 일괄처리를 수행하게 되며 사용자에게 빠른 응답이 필요하지 않은 서비스에 적용할 수 있다. 특정 시간이후에는 자원을 거의 소비하지 않는 것이 특징이다.

Spring Batch

Spring Batch 는 로깅/추적, 트랜잭션 관리, 작업 처리 통계, 작업 재시작, 건너뛰기 등 대용량 레코드 처리에 필수적인 기능을 제공합니다. 또한 최적화 및 파티셔닝 기술을 통해 대용량 및 고성능 배치 작업을 가능하게 하는 고급 기술 서비스 및 기능을 제공합니다.

Spring Batch에서 배치가 실패하여 작업 재시작을 하게 된다면 처음부터가 아닌 실패한 지점부터 실행을 하게 됩니다.

또한 중복 실행을 막기 위해 성공한 이력이 있는 Batch는 동일한 Parameters로 실행 시 Exception이 발생하게 됩니다.

Spring Batch vs Quartz? Scheduler?

Spring Batch는 Scheduler가 아니기에 비교 대상이 아닙니다.

Spring Batch는 Batch Job을 관리하지만 Job을 구동하거나 실행시키는 기능은 지원하고 있지 않습니다. Spring에서 Batch Job을 실행시키기 위해서는 Quartz, Scheduler, Jenkins등 전용 Scheduler를 사용하여야 합니다.

Spring Batch 용어

Job

Job은 배치처리 과정을 하나의 단위로 만들어 놓은 객체입니다. 또한 배치처리 과정에 있어 전체 계층 최상단에 위치하고 있습니다.

JobInstance

JobInstance는 Job의 실행의 단위를 나타냅니다. Job을 실행시키게 되면 하나의 JobInstance가 생성되게 됩니다. 예를들어 1월 1일 실행, 1월 2일 실행을 하게 되면 각각의 JobInstance가 생성되며 1월 1일 실행한 JobInstance가 실패하여 다시 실행을 시키더라도 이 JobInstance는 1월 1일에 대한 데이터만 처리하게 됩니다.

JobParameters

JobInstance는 Job의 실행 단위라고 했습니다. 그렇다면 JonInstance는 어떻게구별 할까요? 이는 바로 JobParameters 객체로 구분하게 됩니다. JobParameters는 JobInstance 구별 외에도 개발자 JobInstacne에 전달되는 매개변수 역할도 하고 있습니다.

또한 JobParameters는 String, Double, Long, Date 4가지 형식만을 지원하고 있습니다.

JobExecution

JobExecution은 JobInstance에 대한 실행 시도에 대한 객체입니다. 1월 1일에 실행한 JobInstacne가 실패하여 재실행을 하여도 동일한 JobInstance를 실행시키지만 이 2번에 실행에 대한 JobExecution은 개별로 생기게 됩니다. JobExecution는 이러한 JobInstance 실행에 대한 상태,시작시간, 종료시간, 생성시간 등의 정보를 담고 있습니다.

Step

Step은 Job의 배치처리를 정의하고 순차적인 단계를 캡슐화 합니다. Job은 최소한 1개 이상의 Step을 가져야 하며 Job의 실제 일괄 처리를 제어하는 모든 정보가 들어있습니다.

StepExecution

StepExecution은 JobExecution과 동일하게 Step 실행 시도에 대한 객체를 나타냅니다. 하지만 Job이 여러개의 Step으로 구성되어 있을 경우 이전 단계의 Step이 실패하게 되면 다음 단계가 실행되지 않음으로 실패 이후 StepExecution은 생성되지 않습니다. StepExecution 또한 JobExecution과 동일하게 실제 시작이 될 때만 생성됩니다. StepExecution에는 JobExecution에 저장되는 정보 외에 read 수, write 수, commit 수, skip 수 등의 정보들도 저장이 됩니다.

ExecutionContext

ExecutionContext란 Job에서 데이터를 공유 할 수 있는 데이터 저장소입니다. Spring Batch에서 제공하느 ExecutionContext는 JobExecutionContext, StepExecutionContext 2가지 종류가 있으나 이 두가지는 지정되는 범위가 다릅니다. JobExecutionContext의 경우 Commit 시점에 저장되는 반면 StepExecutionContext는 실행 사이에 저장이 되게 됩니다. ExecutionContext를 통해 Step간 Data 공유가 가능하며 Job 실패시 ExecutionContext를 통한 마지막 실행 값을 재구성 할 수 있습니다.

JobRepository

JobRepository는 위에서 말한 모든 배치 처리 정보를 담고있는 매커니즘입니다. Job이 실행되게 되면 JobRepository에 JobExecution과 StepExecution을 생성하게 되며 JobRepository에서 Execution 정보들을 저장하고 조회하며 사용하게 됩니다.

JobLauncher

JobLauncher는 Job과 JobParameters를 사용하여 Job을 실행하는 객체입니다.

ItemReader

ItemReader는 Step에서 Item을 읽어오는 인터페이스입니다. ItemReader에 대한 다양한 인터페이스가 존재하며 다양한 방법으로 Item을 읽어 올 수 있습니다.

ItemWriter

ItemWriter는 처리 된 Data를 Writer 할 때 사용한다. Writer는 처리 결과물에 따라 Insert가 될 수도 Update가 될 수도 Queue를 사용한다면 Send가 될 수도 있다. Writer 또한 Read와 동일하게 다양한 인터페이스가 존재한다. Writer는 기본적으로 Item을 Chunk로 묶어 처리하고 있습니다.

ItemProcessor

Item Processor는 Reader에서 읽어온 Item을 데이터를 처리하는 역할을 하고 있다. Processor는 배치를 처리하는데 필수 요소는 아니며 Reader, Writer, Processor 처리를 분리하여 각각의 역할을 명확하게 구분하고 있습니다.

Spring Batch 사용하기

Spring Batch에서의 Job은 여러가지 Step의 모음으로 구성되어 있으며 Job은 순차적인 Step을 수행하며 Batch를 수행하게 됩니다. Step은 Tasklet 처리 방식과 Chunk 지향 처리 방식을 지원하고 있습니다.

이 이상은 다음 참고 링크에 가면 더 자세하게 나와 있습니다.

Spring Batch란? 이해하고 사용하기(예제소스 포함) :: 히진쓰의 서버사이드 기술 블로그 (tistory.com)

[스프링/Spring] Batch 구조와 구성 요소 | Deeplify

Spring Batch와 Scheduler

반응형

1. 스프링 배치

특정한 시간에 내가 원하는 일을 자동으로 시키는게 스케줄러의 역할이고 처음에 이것에 대해 먼저 학습을 하여 스프링 배치에 대한 개념에 혼동이 왔다. 둘이 비슷하다고 생각했지만 아예 다른 개념이였다. 배치는 ‘일괄처리’ 라는 의미이다. 그리고 스프링에서 배치 작업 단위를 Job이라고 부른다. 스프링에서는 배치 작업이 원활하게 진행되도록 관련 기능을 제공해준다. 대용량 배치와 트랜잭션 기능을 간단하게 구현할 수 있다.

매일 전 날의 데이터를 집계해야한다고 가정해보자.

이 집계 과정을 어디서 수행하면 될까?

만약 이 작업을 Tomcat + Spring을 통해 집계를 수행한다면 컴퓨터의 CPU, I/O 등의 자원을 모두 사용 해버려 다른 요청을 처리할 수 없게 될 것이다.

보통 데이터를 집계하는 경우 집계 작업은 하루에 한번만 수행하게 된다. 이를 위해 API를 구성하는 것은 낭비일 수 있다.

단발성 대용량 데이터를 처리하는 애플리케이션을 배치 어플리케이션이라고 한다.

배치는 다음 조건을 만족해야한다.

대용량 데이터 – 대량의 데이터를 가져오거나, 전달하거나, 계싼하는 등의 처리를 할 수 있어야한다.

자동화 – 심각한 문제 해결을 제외하고 사용자 개입없이 실행되어야 한다.

견고성 – 잘못된 데이터를 충돌 / 중단 없이 처리할 수 있어야 한다.

신뢰성 – 무엇이 잘못되었는지를 추적할 수 있어야한다. (로깅, 알림)

성능 – 지정한 시간안에 처리를 완료하거나 동시에 실행되는 다른 어플을 방해하지 않도록 수행되어야 한다.

Batch 사용 사례

일매출 집계

많은 거래가 이루어지는 커머스 사이트의 경우 하루 거래건이 50만 ~ 100만건까지 발생한다.

이를 실시간 집계 쿼리로 해결하기엔 조회 시간이나 서버에 부하가 심해진다.

그래서 매일 새벽 전날 매출 집계 데이터를 만들어 외부 요청이 올 경우 미리 만들어둔 집계 데이터를 바로 전달하여 성능저하와 부하를 해결한다.

이러한 배치를 주기적으로 동작하게 해주는 Scheduler는 대표적으로 2가지가 존재한다.

Quartz 스케줄러

스프링 스케줄러

2. Quartz 스케줄러

스케줄러란 단순히 잡을 특정 시간마다 실행되도록 도와주는 프로그램을 의미한다. Quartz에는 크게 3가지로 이뤄짐

실행하고자 하는 Job job의 실행 주기를 나타내는 trigger 트리거들을 스케줄러로 만드는 scheduler

사용 방법

pom.xml에 관련 dependency 추가 job으로 batch 작업을 진행할 서비스 구현 context.xml에 2번에서 만든 job을 정의할 jobDetailFactoryBean, jobDetail와 연결해 실행주기를 정의할 cronTriggerFactoryBean, 트리거를 스케줄러로 생성해줄 SchedulerFactoryBean 3가지를 설정한다.

3. 스프링 스케줄러

스프링 3.1 버전부터 스프링에서 제공해주는 스케줄러다. Quartz보다 스케줄러를 디테일하게 사용하도록 하진 않지만 구현이 매우 간단하다.

어노테이션으로 설정

xml 파일 상위에 xmlns 설정

설정

xml 파일에 설정 추가

job으로 사용될 서비스 메소드명에 @Scheduler(cron 설정) 추가

자세한 설정 방법 링크

https://smujihoon.tistory.com/136

출처

https://jaegoon.netlify.com/posts/batch/

https://jojoldu.tistory.com/324?category=635883

해당 게시글이 도움이 되셨다면 광고 클릭한번 부탁드립니다 ㅎㅎ

반응형

Spring Batch initializr / 스케쥴러 만들기

목적

한 줄 요약 > 데이터의 반복 처리, 가공, 시간 기반 이벤트 처리를 위해 사용

활용 범위 확장 > logging/tracing, 트랜잭션 관리, 잡 프로세싱 통계, 잡 재시작, 스킵, 리소스 관리 등

발췌 : Spring Batch Introduction -https://docs.spring.io/spring-batch/docs/current/reference/html/spring-batch-intro.html#spring-batch-intro

개발환경

What You Need About 15 minutes

💻 JDK 1.8 or later / Gradle 4+ or Maven 3.2+

IDE: Spring Tool Suite (STS) /IntelliJ IDEA

Basic Sample

Download and unzip the source repository for this guide, or clone it using Git: git clone

“https://github.com/spring-guides/gs-batch-processing.git”

@BatchProcessingApplication.java

Apply Spring Boot’s Application Exit support

package com . example . batchprocessing ; import org . springframework . boot . SpringApplication ; import org . springframework . boot . autoconfigure . SpringBootApplication ; @SpringBootApplication public class BatchProcessingApplication { public static void main ( String [ ] args ) throws Exception { System . exit ( SpringApplication . exit ( SpringApplication . run ( BatchProcessingApplication . class , args ) ) ) ; } }

@BatchConfiguration.java

Switch to tabs, and adjust tabsizing in asciidoctor.

@Configuration @EnableBatchProcessing public class BatchConfiguration { @Autowired public JobBuilderFactory jobBuilderFactory ; @Autowired public StepBuilderFactory stepBuilderFactory ; @Bean public FlatFileItemReader < Person > reader ( ) { return new FlatFileItemReaderBuilder < Person > ( ) . name ( “personItemReader” ) . resource ( new ClassPathResource ( “sample-data.csv” ) ) . delimited ( ) . names ( new String [ ] { “firstName” , “lastName” } ) . fieldSetMapper ( new BeanWrapperFieldSetMapper < Person > ( ) { { setTargetType ( Person . class ) ; } } ) . build ( ) ; } @Bean public PersonItemProcessor processor ( ) { return new PersonItemProcessor ( ) ; } @Bean public JdbcBatchItemWriter < Person > writer ( DataSource dataSource ) { return new JdbcBatchItemWriterBuilder < Person > ( ) . itemSqlParameterSourceProvider ( new BeanPropertyItemSqlParameterSourceProvider < > ( ) ) . sql ( “INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)” ) . dataSource ( dataSource ) . build ( ) ; } @Bean public Job importUserJob ( JobCompletionNotificationListener listener , Step step1 ) { return jobBuilderFactory . get ( “importUserJob” ) . incrementer ( new RunIdIncrementer ( ) ) . listener ( listener ) . flow ( step1 ) . end ( ) . build ( ) ; } @Bean public Step step1 ( JdbcBatchItemWriter < Person > writer ) { return stepBuilderFactory . get ( “step1” ) . < Person , Person > chunk ( 10 ) . reader ( reader ( ) ) . processor ( processor ( ) ) . writer ( writer ) . build ( ) ; } }

@JobCompletionNotificationListener.java

Use the Spring Initializr

@Component public class JobCompletionNotificationListener extends JobExecutionListenerSupport { private static final Logger log = LoggerFactory . getLogger ( JobCompletionNotificationListener . class ) ; private final JdbcTemplate jdbcTemplate ; @Autowired public JobCompletionNotificationListener ( JdbcTemplate jdbcTemplate ) { this . jdbcTemplate = jdbcTemplate ; } @Override public void afterJob ( JobExecution jobExecution ) { if ( jobExecution . getStatus ( ) == BatchStatus . COMPLETED ) { log . info ( “!!! JOB FINISHED! Time to verify the results” ) ; jdbcTemplate . query ( “SELECT first_name, last_name FROM people” , ( rs , row ) -> new Person ( rs . getString ( 1 ) , rs . getString ( 2 ) ) ) . forEach ( person -> log . info ( “Found <" + person + "> in the database.” ) ) ; } } }

Model

배포 관리를 통해 job실행 / jobLauncher를 실행> jobRespository > @Scheduled 어노테이션으로 예약된 Quartz cron 시간 이벤트 발생 > 해당하는 job /Configuration Step 에 따라 순차 처리

Cron Job list는 프로퍼티로 세팅, 배포 없이 사용유무 관리를 위해서 DB 유효성 체크 서비스를 추가하는 것이 보편적인 비지니스 모델인 것 같다

진행

1차 요청 : 스프링 배치 프로젝트 init 구성 > 푸쉬 메시지 관리 sample job

220208~220209

ㄴ 스프링 배치 프로젝트 init 구성

ㄴ Cron job 실행 완료 (DB 연결/확장 제외)

220211

ㄴ AWS ec2 설치된 DB로 ssh 세션 터널링 연결

ㄴ MyslqDbConfig 설정 추가

+

왜 스프링 배치를 사용하는지 / 어떠한 문제를 해결할 수 있는지

멱등성은 어떻게 유지하는가? 데이터 전후 처리를 어떻게 판단하고 관리하였는가

중간 과정에서 에러, 실패 처리는 어떻게 하였는가

multi Thread <> partioning 처리 / 운영 방식

트랜지션 Chunk 단위로 관리하는 이유?

tasket model vs model /processor / writer ?

curson <> page 기반 클래스

배치 실행 / 구동은 어떻게 하였는지

배치 잡 모니터링 관리는 어떻게 하였는지 / 지연관리

참고 자료

https://okdevtv.com/mib/spring/batch

https://spring.io/guides/gs/batch-processing/

https://docs.spring.io/spring-batch/docs/current/reference/html/spring-batch-intro.html#spring-batch-intro

Spring으로 배치 만들기 (quartz, scheduler,task)

반응형

스프링에는 일괄 처리(batch processing) 배치를 만드는 여러가지의 기능이 있다.

방법1. quartz 스케줄링 객체 사용

방법2. 설정 사용

방법3. @Scheduled 어노테이션 사용

실행환경 Spring4 / java 1.8

org.quartz-scheduler quartz 2.3.2 org.springframework spring-context-support 4.3.4.RELEASE

pom.xml에 위의 내용을 dependency추가 한다.

1. quartz 스케줄링 객체 사용

context-batch.xml

배치를 위하 클래스 작성

OneScheduling.java

@Component(“jobComponent”) public class OneScheduling{ private static final Logger logger = LoggerFactory.getLogger(HomeController.class); public void jobMethod() throws Exception { Calendar calendar = Calendar.getInstance(); SimpleDateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”); logger.info(“스케줄 실행 : ” + dateFormat.format(calendar.getTime())); } }

위의 클래스에서 Controller, Servce , Dao를 사용 하고 싶으면 반드시 위의 xml에 컴포포넌트 스캔 한줄을 넣어야 한다.

2. 설정 사용

context-batch.xml

task정보를 설정하고 cron식으로 시간을 설정한다.

Spring Schedule을 실행시키기 위해서는 task가 실행되는 시간/주기 등을 설정하게 되는데 이러한 cron의 표현식에 대한 자세한 설명을 한다.

cron 표현식

문자열의 좌측부터 우측까지 아래의 순서대로 의미가 있고 각 항목은 space 문자로 구분한다.

순서 필드명 사용 가능한 값 1 seconds 0~59 , – * / 2 minutes 0~59 , – * / 3 hours 0~23 , – * / 4 day of month 1~31 , – * ? / L W 5 month 1~12 or JAN-DEC , – * / 6 day of week 1-7 or SUN-SAT , – * ? / L # 7 years (optional) 1970~2099 , – * /

특수문자의 의미

기호 의미 사용 예 * 모든 수를 의미 seconds에서 사용하면 매초, minutes에서 사용하면 매분, hours에서 사용하면 매시간 ? 해당 항목을 사용하지 않음 day of month에서 사용하면 월중 날짜를 지정하지 않음. day of week에서 사용하면 주중 요일을 지정하지 않음 – 기간을 설정 hours에서 10-12이면 10시, 11시, 12시에 동작

minutes에서 58-59이면 58분, 59분에 동작 , 특정 시간을 지정 day of week에서 2,4,6이면 월,수,금에만 동작함 / 시작시간과 반복 간격 설정 seconds위치에 0/15로 설정하면 0초에 시작해서 15초 간격으로 동작

minutes위치에 5/10으로 설정하면 5분에 시작해서 10분 간격으로 동작 L 마지막 기간에 동작

day of month, day of week에서만 사용 day of month에서 사용하면 해당월 마지막 날에 수행

day of week에서 사용하면 토요일에 수행 W 가장 가까운 평일 동작

day of month에만 사용 15W로 설정하면 15일이 토요일이면 가장 가까운 14일 금요일에 실행

15W로 설정하고 15일이 일요일이면 16일에 실행

15W로 설정하고 15일이 평일이면 15일에 실행 LW L과 W의 조합 그달의 마지막 평일에 동작 # 몇 번째 주와 요일 설정

day of week에 사용 6#3이면 3 번째 주 금요일에 동작

4#2이면 2번째 주 수요일에 동작

사용 예

표현식 의미 0 0 12 * * * 매일 12시에 실행 0 15 10 * * * 매일 10시 15분에 실행 0 * 14 * * * 매일 14시에 0분~59분까지 매분 실행 0 0/5 14 * * * 매일 14시에 시작해서 5분 간격으로 실행 0 0/5 14,18 * * * 매일 14시, 18시에 시작해서 5분 간격으로 실행 0 0-5 14 * * * 매일 14시에 0분, 1분, 2분, 3분, 4분, 5분에 실행 0 0 20 ? * MON-FRI 월~금일 20시 0분 0초에 실행 0 0/5 14 * * ? 아무요일, 매월, 매일 14:00부터 14:05분까지 매분 0초 실행 (6번 실행됨) 0 15 10 ? * 6L 매월 마지막 금요일 아무날이나 10:15:00에 실행 0 15 10 15 * ? 아무요일, 매월 15일 10:15:00에 실행 * /1 * * * * 매 1분마다 실행 * /10 * * * * 매 10분마다 실행

이전 Task와 Delay 설정

표현 의미 fixed-delay 이전에 실행된 task의 종료시간으로부터 정의된 시간만큼 지난 후 다음 task를 실행

밀리세컨드 단위 fixed-rate 이전에 실행된 task의 시작 시간으로부터 정의된 시간만큼 지난 후 다음 task를 실행

밀리세컨드 단위

스케줄링 작업(task)을 여러개 설정하고 싶을 경우 태그를 추가 작성한다.

TowScheduling.java

package com.devmg.app.batch; import java.text.SimpleDateFormat; import java.util.Calendar; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import com.devmg.app.HomeController; @Component(“jobComponent”) public class TowScheduling{ private static final Logger logger = LoggerFactory.getLogger(HomeController.class); public void jobMethod() throws Exception { Calendar calendar = Calendar.getInstance(); SimpleDateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”); logger.info(“스케줄 실행 : ” + dateFormat.format(calendar.getTime())); } }

위의 클래스에서 Controller, Servce , Dao를 사용 하고 싶으면 반드시 위의 xml에 컴포포넌트 스캔 한줄을 넣어야 한다.

3. @Scheduled 어노테이션 사용

지금까지의 방법 중에서 제일 간단한 방법이다. 배치기능의 클래스를 빈으로 등록하고 자바에서 크론설정을 한다.

context-batch.xml

어노테이션 검색 코드를 추가한다.

ThreeScheduling.java

public class ThreeScheduling{ private static final Logger logger = LoggerFactory.getLogger(HomeController.class); @Scheduled(cron=”0/1 * * * * *”) // 1초 주기로 실행하라는 의미 public void jobMethod() throws Exception { Calendar calendar = Calendar.getInstance(); SimpleDateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”); logger.info(“스케줄 실행 : ” + dateFormat.format(calendar.getTime())); } }

@Schduled 어노테이션에 cron 표현식을 사용한다.

반응형

Spring Boot Batch Job + Scheduler Simple Example

Spring Boot Batch Job + Scheduler Simple Example

In a previous post we had implemented a Spring Boot Hello World Application. In that the Batch Job got triggered by a REST API call. In this post we develop a simple Spring Boot Batch application where batch job gets triggered using a scheduler.Consider the simple use case where the user wants to delete files from a particular location everyday at a particular time. We will schedule this batch job using the scheduler.

Lets Begin-

4.0.0 com.javainuse springboot-batch 0.0.1 jar SpringBatch Spring Batch-Spring Boot org.springframework.boot spring-boot-starter-parent 1.4.3.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-batch org.springframework.boot spring-boot-maven-plugin

The project will be as follows-

프로도의 개발 블로그 :: [SPRING] 스프링 배치에서 사용되는 Quartz 배치 스케줄링

728×90

스프링 배치 실습을 하는 과정에서 무중단배포가 가능한 스케줄링 기능이 필요했다.

현업에서도 이미 적용중이고, 스프링 배치 내에서 커버할 수 있는것도 한계점이 있다.

예를들어 Job 실행 중에 오류가 발생할 경우 예외처리로 FaultTolerant(내결함성)를 통해 pass를 시킬수 있지만

이것은 어디까지 임시방편으로 처리하는것으로 밖에 안된다.

1. ItemReader, ItemProcess, ItemWriter 에서 설정된 Exception이 발생했을 경우 (Skip)

2. ItemProcess, ItemWriter 에서 설정된 Exception이 발생했을 경우 (Retry)

따라서 job이 실행될 때 여부와 상관없이 가장 먼저 스케줄링을 통해 제어하는 방식이 더 효율적이라 볼 수 있다.

쿼츠에 대해 알아보자.

쿼츠(Quartz)

오픈소스 실시간 스케줄링, 서버 간 클러스터 기능

자바 환경의 규모와 상관없이 사용이 가능하고 Job 실행에 유용한 Spring boot 지원과 같이 오래전부터 스프링 연동을 지원하고있다.

쿼츠는 아래 3가지 컴포넌트를 제공한다.

1. 스케줄러(Scheduler)

스케줄러는 SchedulerFactory 를 통해서 가져올 수 있으며 JobDetails 및 트리거의 저장소 기능을 한다.

예시코드

public JobDetail buildJobDetail(Class job, String name, String group, Map params) { JobDataMap jobDataMap = new JobDataMap(); jobDataMap.putAll(params); return newJob(job).withIdentity(name, group) .usingJobData(jobDataMap) .build(); }

2. 잡(Job)

3. 트리거(Trigger)

작업 실행 시점을 정의한다.

트리거가 작동되어 쿼츠에게 잡을 실행하도록 지시하면, 잡의 개별 실행을 정의하는 JobDetails 객체가 생성된다.

예시코드

public Trigger buildJobTrigger(String scheduleExp) { return TriggerBuilder.newTrigger() .withSchedule(CronScheduleBuilder.cronSchedule(scheduleExp)).build(); }

스프링 배치 작업

* 해당 실습은 스케줄러 시간에 따라 파일을 읽어들이고, api 통신하는 시간을 각각 나누어 진행한다.

– 파일 읽어들이기 (FileSchJob)

package com.example.springbatch.project.scheduler; import lombok.SneakyThrows; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.batch.core.*; import org.springframework.batch.core.explore.JobExplorer; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.quartz.QuartzJobBean; import org.springframework.stereotype.Component; import java.util.Date; import java.util.List; import java.util.stream.Collectors; // QuartzJobBean 을 사용하여 스프링 배치 잡을 기동하는 쿼츠 잡 작성 @Component public class FileSchJob extends QuartzJobBean { @Autowired private Job fileJob; @Autowired private JobLauncher jobLauncher; @Autowired private JobExplorer jobExplorer; // jobRepository의 read 기능만 가지고 있음 /** * 배치를 실행시키는 구문 : 스케줄링된 이벤트가 발생할때마다 한번씩 호출된다. * @param context * @throws JobExecutionException */ @SneakyThrows @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { String requestDate = (String) context.getJobDetail().getJobDataMap().get(“requestDate”); JobParameters jobParameters = new JobParametersBuilder() .addLong(“id”, new Date().getTime()) .addString(“requestDate”, requestDate) .toJobParameters(); // 모든 job의 인스턴스 갯수를 가져올수 있음. int jobInstanceCount = jobExplorer.getJobInstanceCount(fileJob.getName()); // 모든 job의 인스턴스 정보를 가져올수 있음. 0번째 부터 카운트 갯수까지 List jobInstances = jobExplorer.getJobInstances(fileJob.getName(), 0, jobInstanceCount); if(jobInstances.size() > 0) { for (JobInstance jobInstance : jobInstances) { // 여러개의 jobExecution을 가져온다. List jobExecutions = jobExplorer.getJobExecutions(jobInstance); List jobExecutionList = jobExecutions.stream() .filter(jobExecution -> jobExecution.getJobParameters().getString(“requestDate”).equals(requestDate)) .collect(Collectors.toList()); // 해당하는 날짜가 1개 이상인경우 배치를 실행하지 않는다. if(jobExecutionList.size() > 0) { throw new JobExecutionException(requestDate + ” already exists”); } } } jobLauncher.run(fileJob, jobParameters); } }

– api 통신 (ApiSchJob)

package com.example.springbatch.project.scheduler; import lombok.SneakyThrows; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.JobParametersBuilder; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.quartz.QuartzJobBean; import org.springframework.stereotype.Component; import java.util.Date; @Component public class ApiSchJob extends QuartzJobBean { @Autowired private Job apiJob; @Autowired private JobLauncher jobLauncher; /** * 배치를 실행시키는 구문 : 스케줄링된 이벤트가 발생할때마다 한번씩 호출된다. * @param context * @throws JobExecutionException */ @SneakyThrows @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { JobParameters jobParameters = new JobParametersBuilder() .addLong(“id”, new Date().getTime()) .toJobParameters(); jobLauncher.run(apiJob, jobParameters); } }

* api 스케줄러 작성

package com.example.springbatch.project.scheduler; import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; import static org.quartz.JobBuilder.newJob; /** * 스케줄러 설정 */ @Component public class ApiJobRunner extends JobRunner { @Autowired private Scheduler scheduler; @Override protected void doRun(ApplicationArguments args) { JobDetail jobDetail = buildJobDetail(ApiSchJob.class, “apiJob”, “batch”, new HashMap()); Trigger trigger = buildJobTrigger(“0/10 * * * * ?”); // 10초마다 실행 try{ scheduler.scheduleJob(jobDetail, trigger); } catch (SchedulerException e) { e.printStackTrace(); } } }

* file 스케줄러 작성

package com.example.springbatch.project.scheduler; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.stereotype.Component; import java.util.HashMap; /** * 스케줄러 설정 */ @Component public class FileJobRunner extends JobRunner { @Autowired private Scheduler scheduler; @Override protected void doRun(ApplicationArguments args) { String[] sourceArgs = args.getSourceArgs(); JobDetail jobDetail = buildJobDetail(FileSchJob.class, “fileJob”, “batch”, new HashMap()); Trigger trigger = buildJobTrigger(“0/30 * * * * ?”); // 30초마다 실행 jobDetail.getJobDataMap().put(“requestDate”, sourceArgs[0]); try{ scheduler.scheduleJob(jobDetail, trigger); } catch (SchedulerException e) { e.printStackTrace(); } } }

* 공통 스케줄러를 통해 상속받아 사용한다.

package com.example.springbatch.project.scheduler; import org.quartz.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; import static org.quartz.JobBuilder.newJob; /** * 공통 스케줄러 설정 */ public abstract class JobRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { doRun(args); } public Trigger buildJobTrigger(String scheduleExp) { return TriggerBuilder.newTrigger() .withSchedule(CronScheduleBuilder.cronSchedule(scheduleExp)).build(); } public JobDetail buildJobDetail(Class job, String name, String group, Map params) { JobDataMap jobDataMap = new JobDataMap(); jobDataMap.putAll(params); return newJob(job).withIdentity(name, group) .usingJobData(jobDataMap) .build(); } protected abstract void doRun(ApplicationArguments args); }

왼쪽사진 file 스케줄러를 통해 파일이 생성되는 결과

가운데사진 db적재된 결과

오른쪽사진 api통신을 통해 적재된 결과

해당 프로젝트는 인프런의 있는 스프링배치 실습을 통해 진행되었다.

해당 결과물은 git을 통해 확인 가능합니다.

https://github.com/prodo-developer/spring-batch

728×90

Spring 배치, 스케쥴러 사용하기 : Quartz, @Scheduled

반응형

Spring 배치, 스케쥴러 사용하기 : Quartz, @Scheduled

이놈들 설정하느라고 황금같은 월요일과 화요일을 썼다.

둘을 사용하는 방법을 아주 잘 알게 된 시간이었으니, 각각을 정리하면서 보람차게 마무리하도록 하자.

Quartz

처음에는 Quartz를 쓰려고 했다. 설정하다보니 알게 된 내용들을 정리하기도 했더랬다.

결론적으로는 프로젝트 환경과 맞지않는 단점을 하나 발견해서 세팅만 열심히 해놓고 쓰지않았다.

2018/10/29 – [PROGRAM/JAVA / JSP] – Spring 3.x + Quartz 연동 시 주의사항

1) Quartz 사용을 위한 기본 설정

pom.xml

org.quartz-scheduler

quartz

1.8.6

org.quartz-scheduler quartz 1.8.6

Spring 3.x을 사용하는 경우는 1.8.6을 사용하자.

Spring 4.x의 경우는 2.x 이상으로 세팅해도 상관없는 듯 하다. (물론 안해봐서 확신할 수 없음)

applicationContext-batch.xml

별도 파일명을 지정했으나, 기존에 있는 applicationContext.xml에 작성해도 관계없다.

만약 신규로 만드는 경우, context-param 설정의, contextConfigLocation 정보를 고쳐줘야 한다.

CheckJob.java

QuartzJobBean () { public class CheckJob extends() { @Override protected void executeInternal (JobExecutionContext context) throws JobExecutionException { System.out.println(“console check log”); } }

반복적으로 수행될 프로그램이다. 물론 테스트이므로 콘솔창에 텍스트 찍는 것으로만 구성하였으나, 별도로 선언한 class 파일의 객체와 그 함수를 호출하는 부분으로 구성해도 되고, 해당 파일 내에서 프로그램을 짜도 된다.

중요한 내용은 QuartzJobBean을 상속받아서 구현해야 한다는 점이다.

스케쥴이 수행될 때, 기본적으로 executeInteral 함수가 호출된다.

위와 같이 설정하고 나면, 10초마다 콘솔에 텍스트가 찍히는 형태로 스케쥴이 수행된다.

이 방식의 단점은, Spring에서 제공하는 @Autowired를 통한 객체주입의 사용이 불가하다.

(아 물론 AppilcationContext를 불러오도록 설정을 추가적으로 하면 가능하나, 아래에서 소개하는 방법이 더 쉽다.)

@Scheduled

위에 저렇게 Quartz 설정을 잘해놓고 결국 변경하게 된 건 아까 발견한 단점때문이다.

기본 설정만으로는 Spring의 최대 이점인 DI (Dependency Injection) 사용이 어렵다.

다시 말해 Controller, Service 등에 선언된 @Autowired 어노테이션으로 주입한 내용을 인식하지 못해서 method call 시 NullPointerException을 마주하게 된다.

검색해보니 다들 ApplicationContext를 별도 주입하는 방식으로 해결한 듯 하나, 설정의 문제인지 해결이 어려워서 Quartz를 포기하고 Spring 자체적으로 제공하는 Scheduler를 사용하게 되었다.

결론적으로는 설정도 더 간단해졌고 스케줄을 설정하는 방식도 더 스프링다워진 듯 하다.

applicationContext.xml

단, 설정 시 조건이 있다.

해당 설정을 어느 파일에 추가해도 관계없으나, 해당 설정파일에 , 설정이 있는 파일에 안에 함께 담는 것이 좋다.

★이 부분이 완전 핵심이다. 이거 아니었으면 내일도 설정 변경하고 있었을 듯….★

설정파일 변경 후, 기존 내용에 문제 생길까봐 별도 파일에 선언해놨는데 이 때도 Scheduled를 잘 인식해서 가져는 왔으나

문제는 @Autowired 된 객체를 인식하지를 못한다는 거다.

근데, 어떤 난리를 쳐도 안되던게 저 설정이 같이 있는 파일에 담았더니 아주 잘된다.

설정 자체도 너무나도 간소하고, 프로그램 내부의 @Autowired도 잘 인식하고.

만약 Spring 프로젝트 내부에서 스케줄링이 필요한 경우가 있다면 이제 Quartz가 아니라 @Scheduled를 사용할 듯 하다.

참고삼아, CheckController 내부의 모습을 간략하게 구현하자면, 다음과 같다.

CheckController.java

@Controller @RequestMapping(value=”/check”) public class CheckController { @Autowired private CheckService checkService; @Scheduled(cron=”0 30 0/2 * * ?”) public void checkForBatch () { checkService.callCheck(); } }

위와 같은 프로그램을 스케줄링으로 돌리려고 했을 때, @Autowired로 주입된 객체를 인식하지 못하면 스케줄링을 수행하다가 에러가 난다.

미래의 나에게 보내는 정시퇴근을 위한 꿀팁

이 글을 보는 모두들 정시퇴근하세욥 ㅋ_ㅋ

반응형

키워드에 대한 정보 스프링 배치 스케줄러

다음은 Bing에서 스프링 배치 스케줄러 주제에 대한 검색 결과입니다. 필요한 경우 더 읽을 수 있습니다.

이 기사는 인터넷의 다양한 출처에서 편집되었습니다. 이 기사가 유용했기를 바랍니다. 이 기사가 유용하다고 생각되면 공유하십시오. 매우 감사합니다!

사람들이 주제에 대해 자주 검색하는 키워드 스프링 부트의 스프링 배치 | CSV를 데이터베이스로 | 기술 입문서

  • techprimers
  • tech primers
  • spring batch with spring boot
  • spring batch tutorial
  • spring batch hands on
  • spring batch example
  • spring batch using step
  • spring batch step by step
  • spring batch examples with spring boot
  • spring batch
  • spring boot with spring batch
  • spring dev tools
  • spring dev tools example
  • spring batch explained
  • spring batch for begineers

스프링 #부트의 #스프링 #배치 #| #CSV를 #데이터베이스로 #| #기술 #입문서


YouTube에서 스프링 배치 스케줄러 주제의 다른 동영상 보기

주제에 대한 기사를 시청해 주셔서 감사합니다 스프링 부트의 스프링 배치 | CSV를 데이터베이스로 | 기술 입문서 | 스프링 배치 스케줄러, 이 기사가 유용하다고 생각되면 공유하십시오, 매우 감사합니다.

Leave a Comment