09:41 — 배포하자마자 터졌다
- 배포 대상: 프록시 로테이션 기능
- 증상: 실서버에서 크롤링 미작동
- 로컬은 정상, 배포 환경에서만 실패
- 이후 55분 동안 커밋 4개 연달아 배포
문제를 하나 고칠 때마다 다음 문제가 드러나는 패턴이었다.
10:12 — 1차 원인: 토큰이 서버에 없었다
가장 먼저 확인한 것 — 프록시 API 토큰:
- GitHub Secrets에
WEBSHARE_API_TOKEN등록됨 - 로컬
.env.example에는 추가돼 있음 -
실제 배포 서버
.env에는 미반영 - 교훈: 코드에서 새 환경변수를 쓰기 시작해도 배포 스크립트가 그 값을 서버까지 자동 이송하지는 않음
조치:
- SSH 배포 스크립트에 토큰 주입 로직 추가
- 배포 검증 단계 추가 —
bookings_count > 0될 때까지 최대 3분 헬스체크 폴링
10:18 — 2차 원인: 서버가 macOS였다
6분 뒤 다시 실패. 방금 추가한 .env 동기화 로직 자체가 문제:
- 사용한 문법:
sed -i "s|...|...|"— GNU sed 방언 - 배포 대상 서버: macOS(BSD sed)
- 결과: 문법 불일치로 스크립트 파손
GNU와 BSD의 sed -i 옵션 문법이 다르다는 건 흔히 알려진 함정인데, 실제로 걸려보고 나서야 수정에 들어갔다.
조치:
-
sed -i제거 -
grep -v "^KEY="로 기존 줄 제외 후mv로 덮어쓰기 - sed 방언 차이를 아예 우회
10:24 — 3차 원인: 예상보다 훨씬 오래 걸렸다
6분 뒤 또 막힘. 토큰 주입도 정상, 동기화 스크립트도 정상 동작:
- 21일치 데이터 프록시 경유 크롤링에 10분 이상 소요
- 기존 헬스체크 대기: 3분(18회 × 10초)
- 구조상 항상 타임아웃
조치:
- 대기 시간 8분(48회 × 10초)으로 확장
- SSH 액션 타임아웃 15분으로 확장
- 6회마다 컨테이너 로그 출력 —
docker logs golf-crawler --tail 5
로그 계측은 같은 종류의 문제가 다시 생겼을 때 원인 파악 시간을 줄이기 위한 선제적 조치였다.
10:36 — 문제를 다시 정의했다
12분 뒤, 근본적인 재검토. 대기 시간 확장 방식의 한계를 인정한 시점:
- 21일치 크롤링 자체가 30분 이상 걸릴 수 있음
- 헬스체크를 아무리 늘려도 지속 가능하지 않음
그래서 접근을 바꿨다. “배포 스크립트가 더 오래 기다리게” 대신, 애플리케이션이 크롤링 도중에도 일부 데이터를 먼저 노출하도록 구조 변경:
- 크롤링 첫째 날 분량 완료 시점에 캐시 갱신
- 이후 3일마다 점진적 갱신
최종적으로 무엇이 바뀌었나
- 헬스체크 기준: “크롤링 완전 종료” → “일부 데이터라도 노출”
- 대기 3분 → 8분 확장(3차 수정)은 유지
- 진짜 해결은 점진적 노출로의 구조 변경(4차 수정)
| 시각 | 무엇을 고쳤나 | 다음에 드러난 문제 |
|---|---|---|
| 09:41 | 프록시 로테이션 기능 배포 | 서버에서 크롤링 실패 |
| 10:12 | 배포 스크립트에 토큰 동기화 추가 | macOS sed 문법 오류 |
| 10:18 | sed 대신 grep+mv 방식으로 변경 | 헬스체크 타임아웃 |
| 10:24 | 대기 8분 확장 + 로그 계측 추가 | 대기 자체가 근본 해법이 아님을 재확인 |
| 10:36 | 점진적 캐시 갱신으로 구조 변경 | (해결) |
남는 교훈
이 55분을 되짚어보면, 매번 “고쳤다”고 생각한 지점이 실은 다음 문제의 전제 조건을 충족시켰을 뿐이었다.
- 토큰이 있어야 sed 문제가 드러남
- sed가 고쳐져야 타임아웃 문제가 드러남
- 타임아웃을 늘려봐야 그게 임시방편이라는 게 드러남
같은 기능 하나가 배포 파이프라인의 여러 층을 순서대로 건드리는 경우 — 이번에 거친 층:
- 시크릿 동기화
- 플랫폼 차이
- 타임아웃 예산
-
애플리케이션 구조
- 대안 전략: 첫 실패에서 곧바로 “근본 원인”을 찾기보다, 매 실패마다 계측을 조금씩 추가해 다음 원인의 탐색 범위를 빠르게 축소