ai-coding-mines목차GitHub

공유호스팅의 프로세스 한도가 감시 래퍼를 자살시킨다

Git · 자동화

증상

백그라운드로 띄운 수집기가 30분~1시간마다 조용히 죽는다. 트레이스백 없음. 로그가 중간에서 끊김.

원인

fork: Resource temporarily unavailable

공유호스팅의 제한 셸은 사용자당 동시 프로세스 수(ulimit -u)가 아주 낮게 잡혀 있다. 그런데 내가 만든 감시 래퍼가 루프마다 이걸 돌렸다.

while [ "$(ps aux | grep -c '[j]ob_name')" -gt 0 ]

ps 1개 + grep 1개 + 본체 1개. 폴링 한 번이 프로세스 슬롯을 세 개 먹는다 → 한도 초과 → 자식이 죽는다.

래퍼가 지키려던 프로세스를 래퍼가 죽이고 있었다.

철칙

  1. 백그라운드 감시 스크립트에 ps·grep 폴링을 넣지 않는다
  2. 동시 실행 방지는 락파일
  3. 장기 작업은 인자를 한 프로세스에 몰아준다. 묶음을 나눠 여러 번 띄우지 않는다
  4. 건마다 부분저장 → 죽어도 진행분이 남는다. 이게 여러 번 살렸다

한도가 걸린 뒤 증상

fork 실패가 뜨면 새 SSH 세션조차 못 연다. 이미 붙은 셸도 명령 실행이 안 된다.

상시 크론 개수가 프로세스 한도를 넘어서 있으면, 배치 몇 개가 겹치는 순간 서로 밀어낸다. 크론 등록 시점에는 각각 하나씩이라 아무도 안 센다.

배치는 하나씩 순차로. "멈춘 것 같다"가 반복되면 이걸 의심한다.

이미지 변환 도구도 같은 이유로 -limit thread 1 + MAGICK_THREAD_LIMIT=1이 필수다. 안 걸면 전량 실패하면서 "완료"로 찍힌다 — 결과 장수를 반드시 확인한다.

추가 처방 세 가지

  1. 착수 전 1회 선검사ps -u "$(id -un)" | wc -l이 임계(예: 12)를 넘으면 그 회차는 skip. 루프 안에서 폴링하는 게 아니라 시작할 때 한 번만 센다
  2. nice -n 10 — 배치 우선순위를 낮춰 SSH 응답을 확보한다
  3. 크론 중복 등록 확인crontab -l | grep -c <이름>이 1인지 본다. 같은 항목이 두 번 등록돼 있으면 한도는 두 배 속도로 찬다