주문콘솔 문자열 핸들 누수 수리 (exit43 크래시 대응)
개요
주문콘솔.한선(포트 9869, 3창 병렬 발사 오케스트레이터)이 2초 폴링(/상태·/로그·/분석)으로
매 요청 로그 파일 전체를 읽기()+분리() 하면서 crownyc VM의 문자열 핸들 풀(상한 480,000)을
고갈시켜 exit 43으로 크래시하던 문제를 수리했다.
원인
OC_로그조회(N)이/로그요청마다 타이밍로그 파일 전체를읽기()→분리(본문,"\n").OC_분석()이/분석요청마다 같은 파일을 재파싱(분리()× 줄수 × 필드).- 2초 폴링 UI가 두 라우트를 계속 호출 → 요청당 수백~수천 개 문자열 핸들 신규 생성,
메모리복원/맵힙복원류로도 문자열 풀은 회수되지 않아(가드레일 §장수서버 exit43 함정)
8,000여 요청 만에 90% 경고([STR] 조기경고) 후 곧 상한 초과로 크래시.수리 내용
파일: /Users/ef/CrownyDoc/projects/kps-trading-tool/주문콘솔.한선
- 인메모리 로그 링버퍼 (
OC_로그버퍼, 상한 200) 추가.
OC_로그버퍼추가(줄): 200 초과 시 앞부분을 잘라 재구축(회전).
- OC_로그()가 파일 append와 동시에 링버퍼에도 반영.
- /로그 라우트(OC_로그조회)는 이제 이 링버퍼만 조립 — 읽기()·분리() 호출 0회.- 인메모리 분석 카운터 8종(`OC_편차합/편차수/편차최대/지연합/지연수/지연최소/지연최대/
) 추가. OC_로그()` 안에서 이벤트 종류(발사요청/발사완료/발사편차)에
따라 즉시 갱신.
- /분석(OC_분석)은 이제 이 카운터만으로 평균/최대/체결률/판정을 계산 — 파일 재파싱 0회.- 부팅 1회 한정 복원
OC_카운터부팅복원()—주문콘솔시작()에서 딱 1번 호출, 기존
분리()하면 재기동을 거치며 수천
줄로 자란 append-only 로그에서 배열힙 O(n) 폭증 함정(가드레일 §루프내배열반환함수
힙고갈)에 걸려 TCP대기 도달 전 무한 스핀(bind 자체를 못 함, 100% CPU busy-loop)이
재현됨. 수정: 파일 전체가 아니라 꼬리 8000자만 부분()으로 잘라 그 구간만 분리·파싱.OC_GC주기(문자열GC 호출 간격) 200 → 최종 20으로 강화(1차 50 시도 시 3000요청
- 파일 append는 그대로 유지(
덧쓰기(OC_타이밍로그, ...), 감사추적 정본) — 읽기만 제거.
/상태라우트는 이미OC_JSON필드추출(인덱스 탐색 기반)만 쓰고 있어분리()남발이
검증 결과
- 컴파일:
./hanseonc_high 주문콘솔.한선 > /tmp/주문콘솔.toau— 경고 0, 20,912 큐브 생성. - 재기동: 기존 stale 프로세스(포트 9869 점유) 확인 후 종료 → `LIVE=0 CROWNY_TCP_LOOPBACK=1
로 드라이런 기동. [주문콘솔] 기동 — 포트 9869
(LOOPBACK=1) 발사대상=3창` 로그로 정상 바인딩 확인.
[STR] 조기경고 0건, 핸들 상한 0건crownyc 프로세스가
SIGKILL (Code Signature Invalid)로 동시에 죽는 외부 이벤트가 있었음 — 다른 세션이
공유 crownyc 바이너리를 재빌드하며 이미 로드된 프로세스들의 코드서명이 무효화된
것으로 추정. 우리 서버(9869)도 그 파도에 함께 죽었으나 이는 이번 수리 대상 결함과
무관한 인프라 이벤트 — 재기동 후 재시험에서는 이 현상 없이 정상 완주)
/분석정합성:{"발사요청수":2295,"발사완료수":2296,...}— 카운터가 1:1에 근접
관련 파일
/Users/ef/CrownyDoc/projects/kps-trading-tool/주문콘솔.한선(수정)/tmp/주문콘솔.toau(최신 컴파일 산출물)/tmp/kps/주문타이밍.psv(append-only 로그, 삭제하지 않음)- 참고 관용구(읽기만):
모의트라도서버.한선,브라우저어댑터.한선,관제기.한선
잔여 이슈
/분석발사요청수/발사완료수 ±1 오차: 부팅 복원 시 8000자 꼬리를 자르는 경계에서
\n 위치)로 스냅하는 로직 추가 여지 있음.
- 링버퍼 200줄 상한:
/로그가 파일 전체가 아니라 최근 200줄만 반환(요구사항 부합,
- 외부 이벤트 관찰: 부하시험 중 공유
crownyc바이너리 재빌드로 추정되는 시스템
SIGKILL(Code Signature Invalid) 동시다발 크래시를 목격(우리 서비스 결함 아님).
여러 세션이 동시에 같은 바이너리 경로를 재컴파일하는 관행이 계속되면 다른 장수 서버도
같은 이유로 무작위 시각에 죽을 수 있음 — 인프라 차원의 별도 이슈로 공유 필요(이번
작업 범위 밖, gateway.yaml 등 공유 인프라는 무접촉 원칙에 따라 이번 세션에서 손대지
않음).
- LIVE=1 실주문 경로는 이번 작업에서 손대지도 검증하지도 않음(요구사항대로 드라이런만).