본문 바로가기
서비스 웹 서비스 개발 앱 개발 AI 알고리즘 개발 AI 컨설팅 AI 마케팅 프로젝트 인사이트 회사소개 고객게시판
운영 엔지니어링 8 MIN READ

예약 작업이 두 번 돌거나 아예 안 돌 때: 배치 실행을 믿을 수 있게 만드는 법

매일 실행되는 작업도 중복·누락될 수 있습니다. 실행 키, 임대 잠금, 멱등성, 재시도, 실행 이력을 결합해 예약 작업을 안전하게 운영하는 방법을 정리합니다.

Category
운영 엔지니어링
Published
Read
8분
Author
네이처프랙탈
예약 작업이 두 번 돌거나 아예 안 돌 때: 배치 실행을 믿을 수 있게 만드는 법 대표 이미지

“매일 오전 9시에 자동 실행”이라고 설정했는데 어떤 날은 같은 결과가 두 개 생기고, 어떤 날은 아예 보이지 않습니다. 예약 작업의 실패는 웹 요청처럼 바로 사용자가 오류 화면을 보는 일이 아니어서 발견도 늦습니다. 특히 고객 보고서 생성, 정산, 알림 발송, 콘텐츠 발행처럼 외부에 결과가 남는 작업은 한 번의 중복이나 누락이 신뢰 문제로 이어집니다. 스케줄러에 시간을 적는 것과 그 날짜의 업무가 정확하게 완료됐음을 증명하는 것은 다른 문제입니다.

스케줄러는 기상 알람이지 완료 보증서가 아니다

실행 시각에 서버가 재시작되거나 네트워크가 끊길 수 있고, 한 작업이 오래 걸려 다음 실행과 겹칠 수도 있습니다. 여러 서버가 같은 예약을 갖고 있다면 둘 다 작업을 시작할 수 있습니다. Kubernetes CronJob 문서도 예약 시각마다 Job 생성이 근사적으로 이루어지며 중복 또는 누락이 있을 수 있으므로 작업을 멱등하게 만들라고 설명합니다. 이는 특정 플랫폼만의 특성이 아니라 분산 실행의 일반적인 경계입니다.

따라서 “언제 실행을 시도할까”와 “어떤 업무 단위를 완료할까”를 분리합니다. 예를 들어 하루치 보고서라면 실행 키를 (작업 종류, 고객 ID, 기준 날짜)로 정의합니다. 같은 키의 작업은 이미 완료됐는지 조회하고, 데이터베이스에 유일 제약을 걸어 중복 결과 저장을 막습니다. 서버 시각이 아니라 업무 기준 시간대와 날짜 경계를 명확히 정해야 자정 근처의 재시도가 어제와 오늘을 혼동하지 않습니다.

예약 시각과 실제 실행, 중복 요청, 실행 누락을 구분하는 작업 상태 흐름
스케줄러가 호출한 사실과 업무 처리가 완료된 사실은 다릅니다.

잠금만으로 중복 문제를 끝낼 수 없다

여러 실행기가 같은 작업을 집으려면 임대 기간이 있는 잠금이나 상태 전이를 사용합니다. 그러나 작업자가 잠금을 얻은 뒤 멈춰 있다가 임대가 만료되고, 다른 작업자가 새 잠금을 받은 후 옛 작업자가 다시 깨어날 수 있습니다. 외부 저장소가 오래된 작업자의 쓰기를 거부하도록 실행 세대 번호나 fencing token을 확인해야 하는 이유입니다. Microsoft의 분산 잠금 예제도 만료된 잠금 소유자의 오래된 쓰기를 막는 fencing token을 보여 줍니다.

외부 이메일이나 결제 API처럼 우리 데이터베이스의 유일 제약으로 막을 수 없는 부작용은 별도의 멱등 키와 송신 이력이 필요합니다. API가 멱등 키를 지원하면 업무 실행 키를 전달하고, 지원하지 않으면 전송 전후 상태를 저장하고 불확실한 결과를 재조회할 방법을 마련합니다. 타임아웃은 “실패”가 아니라 “결과를 모름”일 수 있습니다. 무조건 다시 보내면 중복이 생깁니다.

재시도와 보충 실행은 다른 경로다

잠깐의 오류는 지수 백오프 등으로 재시도할 수 있지만, 잘못된 입력이나 권한 오류를 무한 재시도하면 문제만 커집니다. 재시도 횟수와 시간 한도를 정하고 실패 원인을 남깁니다. 한편 서버 점검으로 아예 시작하지 못한 날짜는 “재시도” 로그가 없습니다. 기대한 예약 실행 목록과 실제 완료 목록을 비교해 누락된 키를 찾아내는 보충 스캐너가 필요합니다. 오래 지난 작업을 자동 보충할지, 사람 승인을 거칠지도 업무별로 다릅니다.

실행 키, 작업 임대, 멱등성 저장, 재시도, 완료 기록의 단계
재시도와 중복 실행을 전제로 안전한 완료 판정을 설계합니다.

운영 대시보드에는 마지막 시도 시각보다 마지막 성공 완료 시각, 대상 날짜, 처리 건수, 실패 건수, 처리 지연을 보여 주세요. “프로세스가 살아 있다”는 알림으로는 보고서가 빠진 사실을 발견할 수 없습니다. 완료 조건도 구체적이어야 합니다. 파일만 생성하고 고객에게 전달되지 않았다면 ‘생성 완료’와 ‘발송 완료’를 별개 상태로 둡니다. 실패한 실행을 수동으로 다시 시작할 때 같은 키를 쓰면 중복 위험을 낮출 수 있습니다.

운영자 화면에는 강제 재실행 버튼보다 먼저 영향 범위를 보여 주는 것이 좋습니다. 해당 날짜에 몇 고객을 처리했고 어느 고객이 실패했는지, 이미 외부로 발송된 결과가 있는지 확인해야 안전하게 이어서 실행할 수 있습니다. 재실행 요청 자체에도 요청자와 사유를 기록하고, 실제 작업은 새 인스턴스가 맡더라도 원래 업무 키와 연결되게 합니다. 이렇게 해야 사후에 “누가 두 번 눌렀는가”가 아니라 “어떤 결과가 최종적으로 남았는가”를 추적할 수 있습니다.

작게 시작하려면 가장 중요한 예약 작업 하나를 고르고, 업무 키와 상태표, 중복 결과를 막는 유일 제약, 누락 감지 알림을 추가해 보세요. 그다음 서버를 중간에 죽이고 같은 작업을 두 번 실행해도 결과가 하나인지 시험합니다. 신뢰할 수 있는 자동화는 “한 번만 실행될 것”이라는 기대가 아니라 여러 번 시도되어도 결과가 안전하고, 빠진 실행을 찾아 복구할 수 있는 구조 위에 세워집니다.

#예약작업 #배치작업 #CronJob #중복실행방지 #멱등성 #분산잠금 #작업모니터링 #운영자동화 #백엔드 #네이처프랙탈

관측성 업무 자동화 품질관리

/ 다음 단계

이런 문제, 직접 겪고 계신가요?

글로 정리한 방법을 실제 환경에 맞춰 적용하는 일까지 함께 하겠습니다.

영업일 기준 3일 이내 회신 · 상담 및 범위 견적 무료