← 목록
기타 2026-06-09 7KB 읽기 7분

크라우니 게이트웨이 한선씨화 — P4 스트랭글러-피그 컷오버 계획

개요

레거시 JS 게이트웨이(bin/cli.jslib/gateway.js 785줄 + lib/ssl.js 753줄, 라이브 :8080/:8443)를 한선씨 게이트웨이(P1 설정/프록시 + P2 TLS_SNI + P3 헬스)로 무중단 교체한다.

스트랭글러-피그(Strangler-Fig) 패턴: 새 구현을 그림자 포트(8081/8444)에서 먼저 돌리고, 헬스가 통과(Ti)하면 라이브 포트(8080/8443)로 승격한 뒤 레거시를 종료한다. 실패 시 즉시 롤백.

  • 오케스트레이션 스크립트: /Users/ef/crowny-gateway/한선게이트웨이/컷오버.한선 (hanseonc_high 컴파일 통과, 드라이런 검증 완료)
  • 산출은 라이브 파일과 분리된 한선게이트웨이/ 하위에 둠.

전제조건 (P1~P3 통합 완료)

단계모듈인터페이스상태
P1설정.한선설정로드(경로)→라우트맵, 호스트매칭(라우트맵,호스트)→upstream통합 필요
P1프록시.한선프록시처리(요청텍스트,호스트,upstream)→응답텍스트 (HTTP 8081 수신→upstream TCP 포워드)통합 필요
P2TLS_SNI.한선인증서선택(도메인)→[cert경로,key경로] (certbot live SAN 우선, 자체서명 폴백)통합 필요
P3헬스.한선헬스체크(upstream)→Ti/Om/Ta, 인증서리로드()→Ti통합 필요
이 4개 모듈을 단일 그림자 기동 엔트리(그림자기동.한선그림자기동.toau)로 합쳐 8081(HTTP)/8444(HTTPS)에서 listen 시켜야 컷오버 단계1이 의미를 가진다.

단계별 체크리스트

단계0 — 그림자 좀비 정리

  • 8081/8444에 남은 이전 그림자 프로세스를 한선게이트웨이 패턴 매칭으로만 TERM
  • 라이브(8080/8443/9100/9878/9907)는 절대 미접촉
  • sleep 1

단계1 — 그림자 기동 (8081/8444)

  • ./crownyc run 그림자기동.toau 백그라운드 기동, 로그 /tmp/그림자게이트웨이.log
  • sleep 2 안정화

단계2 — 그림자 헬스 검증 (Ti/Om/Ta 게이트)

  • curl /health → 200 (Ti) 확인
  • 백엔드 tiomta 127.0.0.1:9878 → 200
  • 백엔드 mpti 127.0.0.1:9907 → 200
  • 모두 Ti(+1)일 때만 단계3 진행. 하나라도 Ta(-1)면 → 롤백

단계3 — 포트 승격 (8081/8444 → 8080/8443)

  • GW_HTTP=8080 GW_HTTPS=8443로 그림자 인스턴스 라이브 포트 재바인딩
  • 승격 직후 curl 127.0.0.1:8080/health 재확인 → Ti
  • 레거시는 아직 살아있음 (무중단 핵심)

단계4 — 레거시 종료

  • 8080/8443에서 bin/cli.js start 패턴 매칭 프로세스만 TERM
  • sleep 1 종료 확인
  • 한선씨 게이트웨이 8080/8443 단독 서빙 확인

무중단 보장 원리

[그림자 검증]                 [승격]                    [정리]
8081/8444 한선씨 기동  →  헬스 Ti  →  8080/8443 재바인딩  →  레거시 cli.js TERM
   레거시 cli.js 계속 라이브 (8080/8443 응답 유지) ─────────────┘ (이 시점에만 종료)

  • 헬스가 통과하기 전까지 레거시는 절대 종료되지 않는다.
  • 승격은 그림자가 라이브 포트에 추가로 바인딩 → 헬스 재확인 → 그 다음에 레거시 종료.
  • 따라서 어느 순간에도 8080/8443에 응답하는 인스턴스가 최소 1개 존재한다.

롤백 절차

발동 조건: 단계2 헬스 Ta(-1) 또는 단계3 승격 후 헬스 실패.

  • 그림자 8081/8444 프로세스 종료 (한선게이트웨이 패턴)
  • 라이브 포트에 올라온 그림자 인스턴스가 있으면 종료 (한선게이트웨이 패턴 한정 — cli.js는 미접촉)
  • 레거시 bin/cli.js start는 계속 라이브 → 운영 영향 0
  • 컷오버실행()-1 반환 시 자동으로 롤백() 분기

회귀 테스트 도메인 목록

승격 후 다음 도메인이 정상 라우팅되는지 확인 (HTTP 200 + 올바른 upstream):

도메인upstream비고
tiomta.com127.0.0.1:9878메인 검증 백엔드, certbot-ext SAN
mpti.127.0.0.1:9907검증 백엔드, certbot-ext SAN
tube.(gateway.yaml)정적/SPA 라우팅
tok.*(gateway.yaml)라우팅
crowny.org(gateway.yaml 코어)코어 라우팅
docs.crowny.org127.0.0.1:4100문서
pkg.crowny.org127.0.0.1:4873Verdaccio
  • TLS: tiomta/mpti는 certbot live crownybus.com-ext SAN으로 인증서 선택되는지 확인.
  • 그 외 도메인은 도메인별 자체서명 <도메인>.crt/.key 폴백 동작 확인.

리스크

리스크영향완화
그림자 헬스 false-positive깨진 인스턴스 승격백엔드 tiomta/mpti 실측 + 승격 후 재확인 2중 게이트
포트 재바인딩 충돌(EADDRINUSE)승격 실패레거시 미종료 상태라 8080 점유 가능 → SO_REUSEPORT 또는 레거시 먼저 SIGHUP graceful 필요(검토)
bin/cli.js start 패턴 오매칭무관 프로세스 종료grep 패턴을 bin/cli.js start로 엄격 한정, 그림자는 한선게이트웨이로 분리
인증서 핫리로드 누락TLS 핸드셰이크 실패P3 인증서리로드()→Ti 호출을 승격 직전 삽입
한선씨 HTTP Content-Length 한글 바이트 불일치한글 본문 잘림Connection:close + Content-Length 생략 (메모리 규칙 준수)
주의: 포트 재바인딩 충돌은 미해결 설계 이슈. 실제 컷오버 전, 레거시를 먼저 graceful(SIGHUP) 시킨 뒤 그림자를 라이브 포트로 올리는 변형(단계3↔4 순서 교환)을 SO_REUSEPORT 가용 여부에 따라 결정해야 한다. 현재 컷오버.한선은 안전한 드라이런(미실행)이며, 실제 실행 전 이 결정이 선행되어야 한다.

관련 파일

  • /Users/ef/crowny-gateway/한선게이트웨이/컷오버.한선 — 오케스트레이션 (드라이런)
  • /Users/ef/crowny-gateway/한선게이트웨이/설정.한선 — P1
  • /Users/ef/crowny-gateway/한선게이트웨이/TLS_SNI.한선 — P2
  • /Users/ef/crowny-gateway/start.한선 — 좀비정리 패턴 참고 원본
  • /Users/ef/crowny-gateway/gateway.yaml — SSOT 라우팅

잔여 이슈

  1. P1 프록시.한선, P3 헬스.한선한선게이트웨이/에 아직 미배치 (병렬 세션 진행 중).
  2. 그림자기동.한선(4모듈 통합 엔트리) 미작성 — 컷오버 단계1이 참조하는 .toau 산출 필요.
  3. 포트 재바인딩 무중단 전략(SO_REUSEPORT vs 순서교환) 미확정.
  4. 실제 컷오버 실행 트리거(드라이런→실행 전환 플래그)는 의도적으로 미구현 (라이브 보호).