transcode.sh 가 잘못된 해상도로 변환본을 만들고 있어서 급히 멈춰야 했다. ffmpeg 프로세스를 찾아 kill 했는데 몇 분 뒤에 다시 떠 있었다.
Table of contents
Open Table of contents
원인 — 스케줄러가 다시 띄운다
이 배치는 상주 프로세스가 아니라 cron 이 주기적으로 실행하는 것이었다. 매분 스케줄러가 돌고 incoming/ 에 대기 중인 파일이 있으면 그 스크립트를 띄운다.
그러니 죽여도 다음 주기에 다시 뜨고 그것도 고치지 않은 옛 코드로 뜬다. 프로세스를 죽이는 행위 자체가 이 구조에서는 아무 효과가 없다.
조치 — 실제 정지 조건
실제 정지 조건은 수정한 스크립트를 배포하는 것이었다. 새 코드가 올라가면 그때부터 올바르게 돈다.
급해서 crontab -e 로 그 줄을 # 으로 막고 배포 뒤에 되돌리는 쪽을 골랐다. 이유는 배포까지 몇 분이 걸리는 동안 잘못된 변환본이 더 쌓이는 것을 막아야 해서다. 대신 그 사이 들어온 원본이 대기열에 밀리는 것을 감수했다. 무엇이 이 프로세스를 띄우는지를 먼저 찾아야 무엇을 막아야 하는지가 정해진다.
막힌 지점 — 복구와 배포의 순서
여기서 큰 실수를 할 뻔했는데 급한 마음에 잘못된 변환본의 복구를 먼저 하려 했다. 복구를 돌려도 다음 주기에 옛 코드가 다시 떠서 복구분을 덮는다.
순서는 crontab 비활성화나 수정 배포가 먼저이고 그다음이 대상 서버 반영 확인이며 복구가 마지막이다. 배포했다고 변환 서버 세 대에 다 반영된 것이 아니므로 md5sum 으로 스크립트를 대조하는 단계를 빼면 일부 서버에서 같은 일이 반복된다.
해 본 것 — 표준 복구기가 빗나간 두 겹
기존 복구 스크립트를 쓰려 했는데 이 유형을 안 고쳤다. 진단이 -f 로 변환본 파일의 존재만 보고 정상으로 판정해서 ffprobe 로 봐야 드러나는 해상도 오류를 걸러 내지 못했다.
교정 쪽은 device_jobs 에 실패 이력이 있는 대상에만 걸리는 게이트에 묶여 있었는데 이번 대상은 작업이 성공으로 기록돼 있어 그 게이트를 못 탔다. 진단은 통과시키고 교정은 대상이 아닌 두 겹으로 빗나가서 결국 게이트 없이 직접 교정을 거는 방식으로 갔다.
주의 — 자기를 잡는 프로세스 검색
프로세스를 확인하는 과정에도 함정이 있었다. ps aux | grep transcode 의 인자에 그 문자열이 들어 있어서 검색이 자기 자신을 매칭하고 있었다.
그러면 없는데도 항상 결과가 나오므로 판정이 오염된다. pgrep -f 로 바꿨는데 매뉴얼대로 이 명령은 자기 자신을 결과로 내지 않는다. 다시 세어 보니 앞서 종료했다고 생각한 서버에 프로세스가 다시 떠 있었다.
정리
- 스케줄러로 뜨는 프로세스는 죽여도 다음 주기에 다시 뜬다
- 무엇이 띄우는지를 찾아야 무엇을 막을지가 정해진다
- 실제 정지 조건은 수정 배포이고 급하면 스케줄을 비활성화한다
- 배포 전에 복구를 돌리면 옛 코드가 복구분을 덮는다
- 배포했다고 끝이 아니라 대상 서버 반영을 확인한다
- 표준 복구 도구가 진단과 교정 양쪽에서 빗나갈 수 있다
- 프로세스 검색이 자기 자신을 잡으면 판정이 오염된다
- 자기 제외 검색으로 다시 세어야 실제 상태가 나온다