게이트웨이 2분주기 사망 근본수정 — VM 문자열풀 GC 갭
개요
게이트웨이(8080, gwlive.toau)가 6/28부터 죽기 시작해 7/5엔
하루 486회(2~3분마다) 사망. 워치독 쿨다운(120s) 탓에 다운타임이 절반 이상 → "웹이 안 열림·새 서비스 확인 지연"의 실체.
원인 해부 (사망 로그 → VM 소스)
- 사망 직전 로그:
[VM] 문자열 핸들 상한(480000) 초과 — 풀 누수 의심 → exit(43)
- crownyc.c
str_new(): GC는 str_count >= str_cap일 때만 실행
- v11 대용량사전 업그레이드 때
STR_INIT_COUNT가 2,097,152로 상향 → cap(2M) > 핸들상한(480k) → GC 트리거가 영영 안 옴 → 요청별 죽은 문자열이 480k까지 쌓이면 GC 0회 상태로 즉사
- 사망 로그에
[STR] 풀한계 없음 = GC 0회 사망 확증. 시작 시점(6/28)이 v11 상향과 일치, 트래픽 증가로 가속(4→486회/일)
수정 (2건)
| # | 파일 | 내용 |
|---|
| 1 | CrownyOS/crownyc/crownyc.c str_new() | exit(43) 전 str_gc() 최후회수 — 죽은 문자열이면 생존. GC 후에도 480k-4096 이상이면(진짜 누수) 기존대로 종료. 백업 crownyc.bak-20260705-strgc |
| 2 | crowny-gateway/한선게이트웨이/gwlive헬스워치독.sh | LISTEN 소멸(사망 확정) 시 쿨다운 없이 즉시 재기동(15s 최소간격만). 기존 FAIL≥2+120s → 사망당 최대 2분 다운 제거 |
검증
- A/B: 60만 일회성 문자열 스트레스 — 구binary
exit(43) / 신binary 생존 0.3s
smoke-test.sh 15/15 PASS
- 게이트웨이 신 VM 재기동 후 1,600회 부하 → 동일 PID 생존,
[VM] 오류 0, 전 도메인 200
- 새 서비스 웹 즉시확인 흐름 정상:
crowny-ports.sh set → 게이트웨이 즉시 라우팅(team.crowny.org 실측)
관련 파일
/Users/ef/CrownyOS/crownyc/crownyc.c (str_new)
/Users/ef/crowny-gateway/한선게이트웨이/gwlive헬스워치독.sh
- 메모리 갱신:
feedback_hanseon_buf_slots_string_pool.md
잔여 이슈
- 참조 생존 문자열의 진짜 누수는 여전히 exit(43) — 게이트웨이 장기 관찰 필요(재발 시
[VM] … GC 후에도 N 생존 메시지로 구분 가능)
- 공유 crownyc 재빌드 → 기존 실행 중 프로세스는 구 VM 그대로(재기동 시 신 VM). 장수 서비스는 점진 반영
2차 해부 (같은 날 밤 — "화면은 열리는데 기능 간헐 실패")
추가 발견 3건 (전부 수정)
| # | 원인 | 수정 |
|---|
| 3 | 워치독 wait 영구블록: probe curl을 인자 없는 wait로 대기 → nohup으로 띄운 gwlive까지 기다림. gwlive가 2분마다 죽던 시절엔 안 보였고, VM 수정으로 gwlive가 안정되자 워치독이 멈춰 8443 감시 중단(공개 경로 다운 방치) | wait "${pids[@]}" 명시 + gwlive disown + 하트비트(/tmp/gwlive-health-hb.txt) |
| 4 | launchd 그룹킬: 워치독 재기동 시 자식(gwlive·stunnel) 연쇄 사망 = 재기동 폭주 | plist AbandonProcessGroup=true |
| 5 | cert-manager SNI 갭: 인증서 발급 후 stunnel SNI 슬레이브 미생성 → 신규 도메인(team 등) 폴백 인증서 서빙 = 브라우저 TLS 실패 | scripts/sni-sync.sh 신설(버킷 SAN↔양쪽 conf 동기화, 멱등) + cert-manager add에 결선. 누락 110+107건 일괄 결선 |
검증
- 8443 고의 kill → 워치독 11초 자동소생 / 하트비트 지속
- team·docs·crowny.org 10/10 연속 200 (인증서 검증 포함, -k 없음)
- 교훈 메모리: feedback_워치독_wait블록_그룹킬 (상호의존 크래시루프가 버그를 가림)