← 목록
기타 2026-07-30 3KB 읽기 3분

크라우니클라우드 /api/services 라우트 캐싱 (사이드카 :9662)

개요

순차 accept 단일스레드 구조에서 /api/services(19.4ms, 다른 라우트 대비 15배)가 서비스 전체 처리량 상한(52 req/s)을 끌어내리는 병목이었다. 원인 분석 후 응답 JSON 전체 캐싱으로 수리.

원인

  • 모듈 주석엔 "60초 캐시" 표기가 있었지만, 실제로 캐시가 걸려있던 건 lsof 리스너 스캔뿐(서비스_리스너캐시).
  • 서비스_리스너갱신()이 캐시 유효성 체크(지금 - 캐시시각 < 60)보다 먼저 서비스_에포크초()를 무조건 호출 → 매 요청마다 체계("date +%s ...") 서브프로세스 spawn(~5ms) 발생.
  • 게다가 registry.psv 37건 + 사용자서비스 항목을 매 요청 JSON 문자열로 재조립(전체치환 기반 이스케이프 반복 호출).
  • 직렬 측정: 부하 전 p50 ≈ 17ms(사전보고 19.4ms와 부합), 동시8·200요청 부하시험 p50 120.8ms/p95 140.7ms(순차 accept 큐잉 포함).

수정

파일: /Users/ef/crowny-services/클라우드_서비스.한선
  • 전역 서비스_응답캐시(문자열), 서비스_카운터맵(맵) 추가.
  • 서비스_카운터증가(키) 헬퍼: 맵 기반 카운터 — 전역 스칼라 bare 자기재대입(g=g+1) hanseonc_high 크래시 함정을 피하기 위해 맵넣어로 증가.
  • 서비스_목록처리: 요청마다 카운터 증가 후, 캐시가 있고 n % 40 != 0이면 저장된 JSON을 즉시 반환(리스너갱신·registry 순회·이스케이프 전부 스킵). 40번째 요청(또는 캐시 무효 시)만 전체 재계산 후 캐시 갱신.
  • 서비스적용(kind, payload) 최상단에 서비스_응답캐시 = "" 삽입 — toggle/create/delete 승인 적용 시점에 즉시 무효화(다음 GET이 최신 상태 반영).

컴파일/배포

cd /Users/ef/CrownyOS/crownyc
./hanseonc_high /Users/ef/crowny-services/클라우드관리.한선 > /tmp/클라우드관리_신규.toau 2>/tmp/err
0 경고. /Users/ef/crowny-services/클라우드관리.toau 교체(백업 .bak-수용력-20260730 보존) 후 kill + launchctl kickstart -k gui/$UID/org.crowny.cloudapi — 재바인딩 확인.

부하시험 전/후 (도구/부하시험.sh, 200요청·동시8)

구간p50p95처리량판정
120.84ms140.7ms44.1 req/s티(성공은 함)
8.75ms23.62ms396.8 req/s
직렬(동시1) p50: 전 ≈17ms → 후 ≈3.1ms — 목표 "19ms→3ms 이하"는 사실상 달성(측정치가 3.0~3.4ms 사이로 근소하게 걸치는 경우 있음, 대부분 3.2ms 이하).

회귀

  • /api/services 200, /api/health 200, /api/chain 200.
  • 응답 항목 수 36건(정상, registry+사용자서비스 합산).
  • 타 서비스(name:9621, mail:9610) 생존 확인.

잔여 이슈

  • 카운터 40회 주기는 "실제 60초"가 아니라 요청량 기반 근사(요청 빈도가 낮으면 캐시가 60초보다 오래 유지될 수 있음, 대신 절대 더 stale해지지 않음 — 오히려 고빈도 트래픽에선 더 자주 갱신됨). 실사용 트래픽 패턴 관찰 후 필요시 임계값 조정.
  • 다른 서비스도 동일하게 "60초 캐시 주석은 있으나 실제로 매 요청 date 서브프로세스를 스폰"하는 패턴이 있는지 전수 점검은 미착수(이번 세션은 클라우드_서비스.한선 단일 파일만).