@Scheduled 운영 — fixedRate·fixedDelay·cron, 예외·겹침·다중 인스턴스·종료
Spring @Scheduled 가 밑에서 쓰는 ScheduledExecutorService 를 직접 돌려, 운영에서 배치가 조용히 멈추거나 겹치거나 두 번 도는 이유와 막는 방법을 코드로 익힙니다.
1. 왜 배우는가
Spring Boot + MyBatis 사내 시스템은 야간 배치·주기 동기화를 @Scheduled 하나로 돌리는 경우가 많습니다. 배포할 때는 인스턴스를 2대 이상 띄워 두는 것도 흔합니다. 이 둘이 만나면 "배치가 어느 날 조용히 멈췄다", "리포트 메일이 두 번 왔다" 같은 사고가 납니다.
실무 배치 레슨에서는 배치 아키텍처와 chunk, 트랜잭션, skip·retry 를 다뤘습니다. 이 레슨은 그 내용을 반복하지 않고 스케줄링 자체, 즉 "언제 다시 돌리는가" 와 "누가 돌리는가" 에만 집중합니다. @Scheduled 가 내부적으로 무엇을 쓰는지 알아야 이 두 질문에 답할 수 있습니다.
배울 내용은 fixedRate·fixedDelay 의 차이, 예외가 스케줄을 죽이는 문제, 스레드 풀 크기, 겹침·다중 인스턴스 방지, cron 표현식과 시간대, 종료 순서 일곱 가지입니다. 코드는 java-src/extension/09_scheduled 에 있고 Main·SafeTask·MiniCron·LeaderLock 네 파일로 구성됩니다.
Main 을 실행하면 순수 JDK ScheduledExecutorService 로 이 일곱 가지를 실제로 재현합니다. @Scheduled 는 결국 이 클래스 위에 얹힌 얇은 층이므로, SES 의 동작을 알면 운영 중 배치 사고의 원인을 코드로 짚을 수 있습니다.