블로그 목록

crontab flock 활용 리눅스 예약 작업 중복 실행 방지 실무 설정 가이드

리눅스 crontab에서 주기적으로 실행되는 작업이 지연될 때 발생하는 프로세스 중복 실행을 flock 유틸리티의 파일 락 메커니즘으로 안전하게 차단하고 시스템 자원을 보호하는 실무 가이드입니다.

개발 crontab flock 활용 리눅스 예약 작업 중복 실행 방지 가이드
리눅스 터미널 환경에서 flock 명령어를 사용하여 crontab 예약 작업의 중복 실행을 제어하는 개념 일러스트

1. 실습 목표와 파일 락(flock) 사전 준비 사항

주기적으로 실행되는 데이터 집계나 외부 API 수집 배치는 네트워크 지연이나 대용량 트랜잭션으로 인해 처리 시간이 crontab 실행 간격보다 길어질 수 있습니다. 이때 이전 프로세스가 종료되지 않은 상태에서 새로운 프로세스가 시작되면 동일한 레코드를 중복 처리하거나 서버 자원을 고갈시키는 심각한 장애가 발생합니다. 이번 실습의 목표는 리눅스 표준 유틸리티인 flock을 활용해 작업이 완료될 때까지 동일한 스크립트가 겹쳐서 실행되지 않도록 안전한 잠금 환경을 구성하는 것입니다.

실습을 진행하기 위해 우분투(Ubuntu) 또는 RHEL 계열의 리눅스 서버 셸 환경에 접속할 수 있어야 합니다. flock 명령어는 대부분의 리눅스 배포판에서 `util-linux` 패키지에 기본 포함되어 있으므로 추가 설치 없이 바로 사용할 수 있습니다. 터미널에서 `flock --version`을 입력해 명령어가 정상 작동하는지 확인하고, 테스트용 스크립트와 락 파일이 생성될 디렉터리 권한을 사전에 점검해 두시기 바랍니다.

리눅스 터미널에서 flock 명령어 설치 여부 및 버전 확인 화면

2. flock 동작 원리와 실행 명령어 기본 구조

flock은 리눅스 커널의 파일 디스크립터 기반 잠금 시스템 호출(flock system call)을 래핑한 CLI 도구입니다. 특정 락 파일에 대해 배타적 잠금(Exclusive Lock)을 획득한 뒤 지정된 명령어를 서브프로세스로 실행하며, 명령어 수행이 끝나 프로세스가 종료되면 획득했던 파일 락을 커널이 자동으로 해제합니다. 따라서 스크립트가 비정상 종료(SIGKILL 등)되더라도 락 파일이 잠긴 채로 남아 다음 실행을 영구히 막는 문제가 발생하지 않는다는 강력한 장점이 있습니다.

중복 실행 방지를 위한 표준 명령어 형식은 `flock -n /경로/락파일명 실행명령어` 구조입니다. 여기서 `-n` 플래그는 non-blocking 옵션으로, 이미 다른 프로세스가 해당 락 파일을 점유하고 있을 경우 대기하지 않고 즉시 종료 상태 코드 1을 반환하며 종료하라는 의미입니다. 만약 `-n` 대신 대기 시간을 지정하고 싶다면 `-w 10`과 같이 타임아웃 초 단위를 지정해 일정 시간 락 획득을 시도한 후 건너뛰도록 구성할 수도 있습니다.

flock 비차단 옵션에 따른 프로세스 파일 락 획득과 해제 흐름도

3. crontab 등록을 위한 구체적인 입력 및 스크립트 예시

실무 환경을 가정하여 1분마다 실행되지만 작업 시간이 때때로 90초 이상 소요될 수 있는 Python 배치 스크립트 `/home/deploy/scripts/sync_orders.py`를 예시로 들어보겠습니다. 먼저 락 파일은 재부팅 시 자동 정리되고 메모리 기반으로 동작하는 임시 디렉터리인 `/var/lock` 또는 `/tmp` 경로를 사용하는 것이 안전합니다. 예를 들어 `/tmp/sync_orders.lock` 파일 경로를 지정합니다.

실제 crontab 등록을 위해 터미널에서 `crontab -e` 명령어를 입력하고 다음 한 줄을 추가합니다.

`* * * * * /usr/bin/flock -n /tmp/sync_orders.lock /usr/bin/python3 /home/deploy/scripts/sync_orders.py >> /home/deploy/logs/sync_orders.log 2>&1`

이 설정은 매 분마다 flock이 `/tmp/sync_orders.lock`의 소유권을 검사하도록 만듭니다. 앞선 분산 작업이 아직 실행 중이라면 새 프로세스는 락 획득에 실패하여 스크립트를 호출하지 않고 즉시 빠져나가며, 성공했을 때만 파이썬 스크립트를 실행하고 표준 출력과 에러를 지정된 로그 파일에 기록합니다.

crontab 에디터에 flock 옵션과 절대 경로를 포함한 실행 구문 입력 예시

4. 기대 결과 확인 및 중복 실행 차단 테스트

설정이 올바르게 작동하는지 검증하기 위해 인위적으로 지연 시간을 발생시키는 테스트를 수행합니다. 셸에서 터미널 창을 두 개 열고, 첫 번째 터미널에서 `flock -n /tmp/test.lock sleep 30` 명령을 실행하여 30초 동안 락을 잡고 있도록 만듭니다. 그 직후 두 번째 터미널에서 동일하게 `flock -n /tmp/test.lock echo "작업 시작"` 명령을 입력해 봅니다.

첫 번째 터미널의 sleep 명령이 유지되는 동안 두 번째 터미널에서는 아무런 텍스트가 출력되지 않고 프롬프트로 즉시 복귀해야 합니다. 이때 두 번째 터미널에서 종료 코드 확인 명령인 `echo $?`를 입력했을 때 `1`이 출력된다면, flock이 락 충돌을 감지하고 새로운 작업을 정상적으로 스킵한 것입니다. 30초가 지나 첫 번째 프로세스가 완전히 끝난 후 다시 두 번째 명령어를 입력하면 잠금이 정상 해제되어 화면에 '작업 시작' 문구가 출력되는 것을 확인할 수 있습니다.

터미널 다중 세션에서 flock 잠금 충돌 시 종료 코드 1 반환 테스트 결과

5. 실무 운영 시 주의점과 권한 관리

flock을 crontab에 적용할 때는 환경 변수와 실행 권한 문제를 반드시 확인해야 합니다. crontab은 일반 사용자의 대화형 셸과 달리 축소된 최소한의 환경 변수(PATH 등)만 로드하므로, `flock`, 파이썬 인터프리터, 스크립트 경로 등 모든 파일은 `which flock` 명령어로 확인한 절대 경로(`/usr/bin/flock`)로 작성해야 경로 탐색 실패를 방지할 수 있습니다.

또한 락 파일이 위치한 디렉터리의 쓰기 권한을 점검해야 합니다. 여러 사용자가 동일한 서버에서 작업을 돌릴 때, 루트 권한으로 생성된 `/tmp/app.lock` 파일을 일반 웹 계정(`www-data` 등)이 덮어쓰거나 열려고 하면 권한 거부(Permission Denied) 오류가 발생하여 스크립트가 아예 실행되지 못할 수 있습니다. 따라서 작업 실행 계정 전용 디렉터리를 생성하여 락 파일을 보관하거나, 스크립트 소유권과 일치하는 계정의 crontab에서 일관되게 등록하는 것이 안전합니다.

crontab 최소 환경변수 확인과 락 파일 디렉터리 권한 점검 다이어그램
조회 1
One&One 상담 이 글의 주제를 우리 업무에 적용하고 싶다면

업무자동화, 홈페이지 제작, 네이버 자동화까지 필요한 흐름을 카카오톡 오픈채팅에서 바로 상담해 드립니다.

  • 실무 적용 방향 정리
  • 자동화·홈페이지·네이버 연계 상담
  • 1:1 오픈채팅 빠른 응답
카카오톡 오픈채팅 상담 업무자동화 원앤원 · 모바일/PC 모두 참여 가능