[Spring] Spring Batch 오류가 났을 때 어떻게 처리할까?

윤성철·2024년 12월 17일

Back-End

목록 보기
19/22
post-thumbnail

서론

사이드 프로젝트에서 03시마다 미션을 종료하고, 인증글 미제출 유저를 강제퇴장처리하는 배치를 수행하고 있다. 배치가 돌면서 오류가 발생했을 때, 이를 어떻게 대처할지를 고민하고 적용한 결과를 기록하고자 한다.

본론

서론에서 언급한 배치 수행 내용은 boolean 타입의 필드를 update하는 쓰기 작업을 수행한다. 다른 레퍼런스를 찾아보면서, CSV 파일을 읽어들이는 경우 데이터의 유효성 검증에 실패한 경우, skip api를 통해 해당 아이템을 건너뛰고 Reader를 처리하는 경우를 많이 보았다.

우리 서비스에서 관리되는 DB 내부 데이터는 저장되기 전 애플리케이션단에서 유효성 검사를 통과한 값들만 저장되기 때문에, 데이터의 유효성을 이유로 skip을 사용할 필요는 없어보였다.

다만, DB서버로 RDS를 사용하고 있기 때문에, 네트워크 이슈를 이유로 DB 연결이 끊어질 수 있고, 또 입출력 이슈가 발생할 수 있어 재시도하도록 step을 구성하는게 적절해보였다.

Step 구성

falutTolerant는 건너뛰거나 재처리하는 기능을 지원하는 API인데, 배치처리의 내결함성을 지원해준다.
위 API는 retryPolicy나 template에 대한 커스텀없이, retryPolicy(), retryAttempt() 등 간단한 설정으로 retry 로직을 구현할 수 있다.

그러나, 코드 가독성(step에 계속 설정값이 붙는게 싫음), 그리고 오류가 발생하거나, 재시도할 때 로그를 커스텀하여 남기기 위해 retryTemplate을 커스텀하여 재시도 로직을 구현하기로 결정했다.

RetryTemplate

Chunk 방식에서 retry 로직이 적용되면, RetryTemplate.execute()안에서 실행된다.
그래서 retryTemplate을 @Bean으로 등록해서, fixedBackOffPolicy를 통해 재시도 간 5초의 대기시간을 갖도록 구성했다. 또한, retryPolicy를 통해 최대 3번까지 재시도하도록 커스텀했다

RetryPolicy

서론에서도 언급했다시피, 네트워크 이슈, DB 연결 이슈로 발생할 Exception 종류를 담도록 retryPolicy를 구성했다.

CustomRetryListener

exception이 발생했을 때, retry를 시도할 때, 재시도 횟수가 초과했을 때 로그를 남기기 위해 customRetryListener를 작성했다.

ItemProcessor

processor에서 금일이 해당 미션의 제출 필수요일인지, 그렇다면 참여자는 금일 인증글을 제출 했는지의 복잡한 검증을 처리하기 때문에, processor에서 retry 로직을 우선 적용했다.

결론

아직 운영 간 배치 수행한적이 없는데, retryPolicy에서 명시한 exception말고도 잠재적인 이슈가 생길거라고 예상한다.

profile
내 기억보단 내가 작성한 기록을 보자..

0개의 댓글