Q피어 (P2P 게이트웨이 메시) — 하트비트+페일오버 판정 정본
개요
다중 노드(맥·가상서버·타 컴퓨터·최종사용자측)가 게이트웨이 역할을 분담하고 한 노드 장애에도
작동하는 P2P 메시 기반. 이번 작업은 "판정 레이어"까지 — 실제 전파(설정 push, DNS 전환)는
상위 레이어(크라우니허브/DNS 다중A레코드) 담당.
무엇을 했는지
- 기존 자산 확인:
/Users/ef/crowny-gateway/lib/피어.한선 부재. 유사 자산 3종 확인
(
crowny-gateway-chain/분산/피어관리자.한선,
crowny-talk/피어.한선,
crowny-monorepo/노드코어/피어.한선) — 전부 도메인 상이(체인/톡/노드코어) + raw 소켓
기반(소켓받기 무타임아웃 함정)이라 재사용 대신 curl 기반(타임아웃 강제) 신규 판정
정본을 작성. 서버 accept 루프는 게이트웨이통합.한선의 TCP대기 재시도+메모리마커/
문자열마크 회수 패턴을 재사용.
Q피어.한선: 피어목록.psv 로드 → curl -m 3 GET / (Host: crowny.org) 하트비트 프로브 →
4상 판정(티=정상 <1s / 옴=느림 1~3s / 타=불응) → 피어상태.psv 기록.
- 설정 동기화 판정: gateway.yaml SHA256을 자기 버전해시로
/q/health에 노출, 상대방
/q/health 조회해 해시 비교 → 일치=티(동기화됨) / 불일치·조회실패=옴(동기화 필요, 로그만).
- 페일오버 목록: 피어상태.psv에서 상태=타 제외한 활성 노드 목록 산출(재프로브 없이도
failover 모드로 재조회 가능).
- HTTP 서빙: 포트 바인딩(TCP대기 재시도 20회×0.3s) 후
/q/health(자기 상태), /q/peers
(피어상태.psv 내용, 요청마다 파일 fresh read라 재기동 없이 최신 반영) 서빙.
- 3모드:
probe(1회 프로브 후 종료) / serve(상주 서버) / failover(재프로브 없이 재판정).
발견한 VM 함정 (신규)
시도는 예약어(TOK_TRY) — 변수명으로 쓰면 "줄 644: 변수명 기대, '시도' 발견" 컴파일
에러. 재시도 카운터는
재시도수 등으로.
- 체계()는 popen 기반으로 stdout을 실제로 캡처한다 (crownyc.c case 449, 8191바이트,
trailing
\n 제거) — 기존 메모리 노트("체계()는 exit code만, stdout 캡처 불가")는 이
경로에선 부정확.
curl ... ; printf '|%s' $? 한 줄로 exit code까지 같은 문자열에 담아
바로 받을 수 있어 임시파일 리다이렉트 없이도 안전(기존 health-monitor.한선/
cert-manager.한선도 이미 이 방식 사용 중이었음, 실측 재확인).
검증 (실행 로그 evidence)
로컬 루프백 2노드(qw1:9151, qw2:9153) + 불응 대조군(qw3:9158, 아무도 리슨 안 함) 시뮬:
- 양쪽 serve 기동 → 상호
/q/health curl 확인, 같은 gateway.yaml 해시 반환.
- qw1 → probe 실행: qw2=티(http200, ~0.0004s), 동기화=티 / qw3=타(http000). 페일오버=[qw2].
- qw1 serve의
/q/peers 재조회 → 방금 기록한 상태 그대로 반환(재기동 불필요, 라이브 확인).
- qw2 → probe 실행: qw1=티/동기화=티, qw3=타. 페일오버=[qw1]. (양방향 상호 하트비트 확인)
- qw2(:9153) 프로세스 kill.
- qw1 → 재probe: qw2=타(http000)로 전환, 페일오버=[](qw2 제외 확인).
- qw1 serve의
/q/peers 재조회(재기동 없이) → 갱신된 타 상태 즉시 반영 확인.
failover 모드(재프로브 없이 피어상태.psv만 재로드) → 동일하게 0개 활성 확인.
- 전부 kill, 포트(9151/9153/9158) 잔여 프로세스 없음 확인. 라이브 게이트웨이(:8080)와
crowny-gateway-monitor(:9152)는 무영향(별도 lsof 확인).
관련 파일
/Users/ef/crowny-gateway/게이트웨이Q/Q피어.한선 (정본, hanseonc_high 컴파일 확인)
/Users/ef/crowny-gateway/게이트웨이Q/Q피어.toau (컴파일 산출물)
/Users/ef/crowny-gateway/게이트웨이Q/Q피어.sh (기동 래퍼, probe/serve/failover 3모드)
/Users/ef/crowny-gateway/게이트웨이Q/피어목록.psv (노드ID|호스트|포트|역할|상태 로스터)
/Users/ef/crowny-gateway/게이트웨이Q/피어상태.qw1.psv, 피어상태.qw2.psv (테스트 산출 상태파일)
- 크라우니코드 학습: intent
Q피어_P2P_하트비트_페일오버_판정 (별칭 Q피어) 등록 완료.
잔여 이슈 / 다음 단계
- 포트 9152는 gateway.yaml에
crowny-gateway-monitor로 이미 등록·점유돼 있어, 원 지시(9152
서빙)를 9151/9153 테스트 포트로 대체함 — 실제 배포 시 포트는
crowny-ports.sh set로
정식 등록 필요(예: q피어.crowny.org 또는 신규 포트 채번).
- 실제 배포 시 다중 호스트(가상서버·타 컴퓨터) 간 curl 프로브는 방화벽/포트포워딩 필요 —
이 세션은 동일 맥 로컬 루프백 검증까지만.
- 설정 동기화 판정은 로그+4상 판정까지만(요구사항 3 그대로) — 실제 gateway.yaml 전파는
크라우니허브가 별도 구현해야 함(이 파일은 트리거하지 않음).
- serve 모드는 상태를 파일에서 매 요청 fresh read만 함 — 자체 백그라운드 재프로브 타이머는
없음(VM에 스레드 없음). 주기 프로브는 외부 cron/launchd로
Q피어.sh probe ...를 반복
호출하는 방식을 권장(이 정본은 판정 로직만 제공).