<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>makgol's note – 설계·개발</title><link>https://docs.makgol.com/engineering/</link><description>Recent content in 설계·개발 on makgol's note</description><generator>Hugo -- gohugo.io</generator><language>ko-KR</language><copyright>© 2026 Mont</copyright><lastBuildDate>Sun, 04 Oct 2026 00:00:00 +0900</lastBuildDate><atom:link href="https://docs.makgol.com/engineering/index.xml" rel="self" type="application/rss+xml"/><item><title>04 Computer Use Agent — 어디에 쓰고 어디엔 쓰지 않나</title><link>https://docs.makgol.com/ai-tools/04-computer-use-agents/</link><pubDate>Tue, 06 Oct 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/ai-tools/04-computer-use-agents/</guid><description>
&lt;h1&gt;04 · Computer Use Agent — 어디에 쓰고 어디엔 쓰지 않나&lt;/h1&gt;&lt;h2&gt;1. CUA를 고르기 전에 확인할 것&lt;span class="hx:absolute hx:-mt-20" id="1-cua를-고르기-전에-확인할-것"&gt;&lt;/span&gt;
&lt;a href="#1-cua%eb%a5%bc-%ea%b3%a0%eb%a5%b4%ea%b8%b0-%ec%a0%84%ec%97%90-%ed%99%95%ec%9d%b8%ed%95%a0-%ea%b2%83" class="subheading-anchor" aria-label="이 섹션에 대한 고유 링크"&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;자동화할 일에 API가 있으면 API부터 씁니다. 화면을 다뤄야 해도 접근성 트리(UI 요소의 역할과 상태를 표현한 트리)나 코드로 처리할 수 있는지 먼저 확인합니다. 화면의 픽셀을 읽고 클릭하는 CUA는 그 경로가 막혔을 때 검토할 마지막 수단입니다.&lt;/p&gt;</description></item><item><title>01 Claude Code 관측 — OTel 내보내기·대시보드·백필</title><link>https://docs.makgol.com/ai-tools/01-claude-code-otel/</link><pubDate>Tue, 08 Sep 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/ai-tools/01-claude-code-otel/</guid><description>
&lt;h1&gt;Claude Code 관측 — 토큰이 어디로 새는지 숫자로 보기&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;2026-10-04 현재 Claude Code는 HyperDX 컬렉터로 보내며, 로그·트레이스는 ClickHouse에, 메트릭은 VictoriaMetrics에 저장합니다. otel-gateway·VictoriaLogs·Tempo를 쓰던 시기의 장애와 측정값은 당시 조건을 붙여 구분했습니다. 수집 경로를 바꾼 과정은 &lt;a href="https://docs.makgol.com/homelab/03-observability-consolidation/"&gt;관측 스택 일원화&lt;/a&gt;에 있습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://docs.makgol.com/homelab/02-dev-workspace/"&gt;홈랩 개발환경 편&lt;/a&gt;의 code-server 터미널에서 Claude Code를 사용합니다. &lt;code&gt;/cost&lt;/code&gt;로 그때그때 비용을 볼 수 있지만, 에이전트별 사용량이나 세션을 새로 열 때의 고정비, 훅이 차지하는 시간까지 비교하기는 어렵습니다. 이를 확인하려고 hub의 VictoriaMetrics·ClickHouse·Grafana로 텔레메트리를 모았습니다. 수집을 붙인 첫날의 관측에 이후 경로 변경과 백필 구성을 함께 기록한 글입니다. 공식 설정 문서는 &lt;a href="https://code.claude.com/docs/ko/monitoring-usage"target="_blank" rel="noopener"&gt;monitoring-usage&lt;/a&gt;를 참고했습니다.&lt;/p&gt;</description></item><item><title>02 Codex CLI 관측과 공통 대시보드 — Claude Code와 한 화면에</title><link>https://docs.makgol.com/ai-tools/02-codex-otel/</link><pubDate>Tue, 22 Sep 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/ai-tools/02-codex-otel/</guid><description>
&lt;h1&gt;Codex CLI 관측과 공통 대시보드 — 두 CLI를 한 화면에서 보기&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;2026-10-04 현재 Codex는 HyperDX 컬렉터로 보내며, 로그·트레이스는 ClickHouse에, delta 메트릭은 VictoriaMetrics에 저장합니다. otel-gateway·VictoriaLogs·Tempo를 쓰던 시기의 설정과 14일 실측은 당시 조건을 붙여 구분했습니다. 수집 경로를 바꾼 과정은 &lt;a href="https://docs.makgol.com/homelab/03-observability-consolidation/"&gt;관측 스택 일원화&lt;/a&gt;에 있습니다.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Claude Code로 작업하면서 1차 코드리뷰와 교차검증은 &lt;code&gt;codex-relay&lt;/code&gt; 에이전트로 Codex에 넘깁니다. &lt;code&gt;~/.claude/CLAUDE.md&lt;/code&gt;에는 haiku &amp;lt; sonnet &amp;lt; opus &amp;lt; fable 순의 티어 규칙을 두었습니다. Anthropic 쿼터를 줄이려는 이 운영 방식이 실제 사용량에 어떻게 나타나는지 보려면 두 CLI의 토큰과 호출을 함께 비교해야 했습니다.&lt;/p&gt;</description></item><item><title>01 워크플로우 · 하네스 · Context/Memory · MCP/A2A</title><link>https://docs.makgol.com/ai-tools/03-agent-concepts/01-concepts/</link><pubDate>Thu, 01 Oct 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/ai-tools/03-agent-concepts/01-concepts/</guid><description>
&lt;h1&gt;에이전트 개념 정리 — 워크플로우 · 하네스 · Context/Memory · MCP/A2A&lt;/h1&gt;&lt;p&gt;LLM으로 답을 생성하는 시스템도 다음 실행 순서를 코드로 고정할 수 있습니다. 반대로 모델이 관측 결과를 보고 도구를 고르는 시스템은 같은 요청에도 다른 경로를 거칠 수 있습니다. 이 차이를 기준으로 워크플로우와 에이전트를 구분하고, 모델 밖에서 실행을 담당하는 하네스와 도구 설계로 이어집니다.&lt;/p&gt;</description></item><item><title>부록 · 발표 전사 — 에이전트, 개념부터 같이 정리해봐요</title><link>https://docs.makgol.com/ai-tools/03-agent-concepts/02-transcript/</link><pubDate>Thu, 01 Oct 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/ai-tools/03-agent-concepts/02-transcript/</guid><description>
&lt;h1&gt;02 · 발표 전사 — 에이전트, 개념부터 같이 정리해봐요&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;p&gt;NAVER D2 발표 「에이전트, 개념부터 같이 정리해봐요 - 워크플로우 · 하네스 · Context/Memory · MCP/A2A」의 전사 정리본입니다. 박슬기(NAVER 광고 프로덕트)가 네이버 사내 Tech Meetup에서 발표했으며, 영상 길이는 1시간 5분 36초입니다.&lt;/p&gt;</description></item><item><title>부록 · STT 원문 — 에이전트, 개념부터 같이 정리해봐요</title><link>https://docs.makgol.com/ai-tools/03-agent-concepts/03-stt-raw/</link><pubDate>Thu, 01 Oct 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/ai-tools/03-agent-concepts/03-stt-raw/</guid><description>
&lt;h1&gt;03 · STT 원문 — 에이전트, 개념부터 같이 정리해봐요&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;p&gt;발표 영상(1시간 5분 36초)을 faster-whisper &lt;code&gt;large-v3-turbo&lt;/code&gt;(CPU, int8, VAD 사용)로 자동 전사한 원본 출력입니다. 오인식(&amp;ldquo;채찍 PT&amp;rdquo;, &amp;ldquo;와일루프&amp;rdquo;, &amp;ldquo;클로즈닷 MD&amp;rdquo; 등)과 말버릇은 그대로이며, 각 타임스탬프는 whisper가 나눈 구간의 시작 시각입니다.&lt;/p&gt;</description></item><item><title>모놀리스와 수직 확장 — 장애 도메인이 하나였던 시절</title><link>https://docs.makgol.com/cellarch/01-monolith/</link><pubDate>Tue, 22 Sep 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/cellarch/01-monolith/</guid><description>
&lt;h1&gt;01 · 모놀리스와 수직 확장 — 장애 도메인이 하나였던 시절&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;확장과 격리는 다른 문제다&lt;/strong&gt; — 앱 서버를 늘리면 처리량은 늘지만, 뒤에 놓인 DB가 하나면 장애 도메인은 그대로 하나로 남는다 &lt;code&gt;Σ&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2008년 eBay 발표는 분할의 두 축을 함께 제시했다&lt;/strong&gt; — Randy Shoup의 &amp;ldquo;Partition by Function&amp;quot;과 &amp;ldquo;Split Horizontally&amp;quot;가 훗날 각각 마이크로서비스와 셀로 갈라져 이어진다 &lt;code&gt;✓&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amazon의 3-tier 전환은 1차 문서로 남아 있지만, 그 뒤 흔히 도는 해체 서사는 2차 출처뿐이다&lt;/strong&gt; — Obidos를 3년에 걸쳐 쪼갰다는 이야기는 출처를 밝히지 않으면 단언할 수 없다 &lt;code&gt;✓&lt;/code&gt;/&lt;code&gt;?&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;근거 표기 — &lt;code&gt;✓&lt;/code&gt; 1차 문서 확인 · &lt;code&gt;Ⓑ&lt;/code&gt; 공개 벤치마크 · &lt;code&gt;Ⓥ&lt;/code&gt; 벤더·프로젝트 주장 · &lt;code&gt;≈&lt;/code&gt; 추정·역산 · &lt;code&gt;?&lt;/code&gt; 미확인 · &lt;code&gt;Σ&lt;/code&gt; 종합 판단.&lt;/p&gt;</description></item><item><title>SOA에서 마이크로서비스로 — 무엇을 나눴고 무엇을 못 나눴나</title><link>https://docs.makgol.com/cellarch/02-microservices/</link><pubDate>Tue, 22 Sep 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/cellarch/02-microservices/</guid><description>
&lt;h1&gt;02 · SOA에서 마이크로서비스로 — 무엇을 나눴고 무엇을 못 나눴나&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bezos의 2002년 API 강제 명령이 SOA 전환의 시작점으로 꼽힌다&lt;/strong&gt; — 원문은 Amazon 공식 문서가 아니라 Steve Yegge가 2011년에 남긴 회고이고, 연도도 &amp;ldquo;2002년경, ±1년&amp;quot;으로만 적혀 있다 &lt;code&gt;?&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hystrix는 격리의 산수를 숫자 하나로 보여줬다&lt;/strong&gt; — 의존성 30개가 각각 99.99%를 지켜도 합성 가용성은 99.7%로 떨어지고, 한 달에 두 시간 넘는 장애로 이어진다 &lt;code&gt;✓&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MSA가 나눈 것은 배포·확장·조직이지 장애 도메인이 아니었다&lt;/strong&gt; — 벌크헤드로 프로세스 안의 격리는 얻었지만, 그 바깥의 공유 인프라 층은 여전히 하나였다 &lt;code&gt;Σ&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;근거 표기 — &lt;code&gt;✓&lt;/code&gt; 1차 문서 확인 · &lt;code&gt;Ⓑ&lt;/code&gt; 공개 벤치마크 · &lt;code&gt;Ⓥ&lt;/code&gt; 벤더·프로젝트 주장 · &lt;code&gt;≈&lt;/code&gt; 추정·역산 · &lt;code&gt;?&lt;/code&gt; 미확인 · &lt;code&gt;Σ&lt;/code&gt; 종합 판단.&lt;/p&gt;</description></item><item><title>MSA가 스케일에서 깨진 지점 — 공유 의존성 하나가 전체를 멈춘 사례들</title><link>https://docs.makgol.com/cellarch/03-shared-failure/</link><pubDate>Tue, 22 Sep 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/cellarch/03-shared-failure/</guid><description>
&lt;h1&gt;03 · MSA가 스케일에서 깨진 지점 — 공유 의존성 하나가 전체를 멈춘 사례들&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;서비스를 나눠도 그 밑의 공유 층이 하나면 폭발 반경은 전체다&lt;/strong&gt; — Uber가 2,200개 마이크로서비스를 운영하며 다시 도메인 단위로 묶어야 했던 이유다 &lt;code&gt;✓&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;지리적 분산은 격리가 아니다&lt;/strong&gt; — Datadog 2023-03, 5개 리전이 같은 OS 이미지 때문에 동시에 쓰러졌다 &lt;code&gt;✓&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;전파가 빠를수록 폭발 반경도 커진다&lt;/strong&gt; — Cloudflare 2025-11-18, 파일 하나가 5분마다 전 네트워크에 실려 갔다 &lt;code&gt;✓&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;근거 표기 — &lt;code&gt;✓&lt;/code&gt; 1차 문서 확인 · &lt;code&gt;Ⓑ&lt;/code&gt; 공개 벤치마크 · &lt;code&gt;Ⓥ&lt;/code&gt; 벤더·프로젝트 주장 · &lt;code&gt;≈&lt;/code&gt; 추정·역산 · &lt;code&gt;?&lt;/code&gt; 미확인 · &lt;code&gt;Σ&lt;/code&gt; 종합 판단.&lt;/p&gt;</description></item><item><title>셀 기반 아키텍처 — 정의, 계보, 해부</title><link>https://docs.makgol.com/cellarch/04-cell-anatomy/</link><pubDate>Tue, 22 Sep 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/cellarch/04-cell-anatomy/</guid><description>
&lt;h1&gt;04 · 셀 기반 아키텍처 — 정의, 계보, 해부&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;셀은 워크로드 전체의 독립 사본이다&lt;/strong&gt; — AWS 백서는 &amp;ldquo;독립적으로 돌아가는 데 필요한 모든 것을 갖춘 완전한 워크로드&amp;quot;라고 정의한다 &lt;code&gt;✓&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;cell&amp;quot;이라는 단어는 세 갈래가 서로 다른 뜻으로 사용했다&lt;/strong&gt; — Google Borg의 스케줄링 도메인, WSO2의 API 조합 단위, AWS의 폭발 반경 격리 단위는 이름만 같고 뜻이 다르다 &lt;code&gt;✓&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;셔플샤딩은 셀이 아니라 셀 안에서 쓰는 조합 기법이다&lt;/strong&gt; — AWS FAQ가 이 둘을 직접 구분해 못 박는다 &lt;code&gt;✓&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;근거 표기 — &lt;code&gt;✓&lt;/code&gt; 1차 문서 확인 · &lt;code&gt;Ⓑ&lt;/code&gt; 공개 벤치마크 · &lt;code&gt;Ⓥ&lt;/code&gt; 벤더·프로젝트 주장 · &lt;code&gt;≈&lt;/code&gt; 추정·역산 · &lt;code&gt;?&lt;/code&gt; 미확인 · &lt;code&gt;Σ&lt;/code&gt; 종합 판단.&lt;/p&gt;</description></item><item><title>셀을 실제로 만든 곳들 — Slack·Roblox·GitLab·Shopify, 그리고 셀을 안 쓴 Uber</title><link>https://docs.makgol.com/cellarch/05-cell-cases/</link><pubDate>Tue, 22 Sep 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/cellarch/05-cell-cases/</guid><description>
&lt;h1&gt;05 · 셀을 실제로 만든 곳들 — Slack·Roblox·GitLab·Shopify, 그리고 셀을 안 쓴 Uber&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;셀 경계는 조직마다 다른 것을 가리킨다&lt;/strong&gt; — Slack은 가용 영역, Roblox는 머신 세트, GitLab은 조직, Shopify는 데이터스토어만 나눈다 &lt;code&gt;✓&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Datadog 2023-03-08은 격리의 반례다&lt;/strong&gt; — 리전은 갈랐지만 OS 업데이트 파이프라인은 전역이라 전 리전이 동시에 멈췄다 &lt;code&gt;Ⓥ&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Uber와 Netflix는 셀을 쓰지 않는다&lt;/strong&gt; — 수천 개 서비스를 굴리는 두 회사는 리전 페일오버와 대피를 택했다 &lt;code&gt;✓&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;근거 표기 — &lt;code&gt;✓&lt;/code&gt; 1차 문서 확인 · &lt;code&gt;Ⓑ&lt;/code&gt; 공개 벤치마크 · &lt;code&gt;Ⓥ&lt;/code&gt; 벤더·프로젝트 주장 · &lt;code&gt;≈&lt;/code&gt; 추정·역산 · &lt;code&gt;?&lt;/code&gt; 미확인 · &lt;code&gt;Σ&lt;/code&gt; 종합 판단.&lt;/p&gt;</description></item><item><title>AWS는 어떻게 가두나 — DynamoDB·Route 53·Lambda·S3의 격리 단위</title><link>https://docs.makgol.com/cellarch/06-aws-isolation/</link><pubDate>Tue, 22 Sep 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/cellarch/06-aws-isolation/</guid><description>
&lt;h1&gt;06 · AWS는 어떻게 가두나 — DynamoDB·Route 53·Lambda·S3의 격리 단위&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AWS의 격리는 셀 하나가 아니라 네 겹이다&lt;/strong&gt; — Region → AZ → cell → shuffle shard, 그리고 이 넷을 가로지르는 control plane / data plane 분리 &lt;code&gt;✓&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;리전 격리에도 예외가 있다&lt;/strong&gt; — IAM·Route 53·CloudFront 같은 글로벌 서비스의 컨트롤 플레인은 &lt;code&gt;us-east-1&lt;/code&gt; 하나에 몰려 있다 &lt;code&gt;✓&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DynamoDB는 이 전부를 한 서비스 안에서 보여준다&lt;/strong&gt; — 파티션·요청 라우터·MemDS·GAC. 다만 논문에 &amp;ldquo;cell&amp;quot;이라는 단어는 없다 &lt;code&gt;✓&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;근거 표기 — &lt;code&gt;✓&lt;/code&gt; 1차 문서 확인 · &lt;code&gt;Ⓑ&lt;/code&gt; 공개 벤치마크 · &lt;code&gt;Ⓥ&lt;/code&gt; 벤더·프로젝트 주장 · &lt;code&gt;≈&lt;/code&gt; 추정·역산 · &lt;code&gt;?&lt;/code&gt; 미확인 · &lt;code&gt;Σ&lt;/code&gt; 종합 판단.&lt;/p&gt;</description></item><item><title>2025-10-20 us-east-1 — 격리가 지킨 것과 못 지킨 것</title><link>https://docs.makgol.com/cellarch/07-aws-2025-outage/</link><pubDate>Tue, 22 Sep 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/cellarch/07-aws-2025-outage/</guid><description>
&lt;h1&gt;07 · 2025-10-20 us-east-1 — 격리가 지킨 것과 못 지킨 것&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;터진 건 DynamoDB의 데이터가 아니라 리전 엔드포인트로 가는 길이었다&lt;/strong&gt; &lt;code&gt;✓&lt;/code&gt; — 파티션·스토리지 노드는 무사했고, 다른 리전도 그대로 돌았다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;경합을 일으킨 건 셀도 샤드도 아닌, 리전당 하나뿐인 DNS 관리 자동화였다&lt;/strong&gt; &lt;code&gt;✓&lt;/code&gt; — 중복 실행이라는 안전장치가 오히려 경합의 재료가 됐다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWS의 개선 약속 4개 중 3개는 셀 분할이 아니라 속도 제한이었다&lt;/strong&gt; &lt;code&gt;✓&lt;/code&gt; — 이 사고는 공간을 나눠서 풀리는 문제가 아니었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;근거 표기 — &lt;code&gt;✓&lt;/code&gt; 1차 문서 확인 · &lt;code&gt;Ⓑ&lt;/code&gt; 공개 벤치마크 · &lt;code&gt;Ⓥ&lt;/code&gt; 벤더·프로젝트 주장 · &lt;code&gt;≈&lt;/code&gt; 추정·역산 · &lt;code&gt;?&lt;/code&gt; 미확인 · &lt;code&gt;Σ&lt;/code&gt; 종합 판단.&lt;/p&gt;</description></item><item><title>JVM vs GraalVM</title><link>https://docs.makgol.com/runtime/01-jvm-graalvm/</link><pubDate>Sat, 29 Aug 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/runtime/01-jvm-graalvm/</guid><description>
&lt;h1&gt;01 · JVM vs GraalVM — 시동을 사면 무엇으로 값을 치르나&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;지도가 2025년 9월에 바뀌었습니다.&lt;/strong&gt; Graal JIT은 Oracle JDK 24가 마지막이고 JDK 25에서 빠졌습니다. Native Image도 Java SE 구독의 지원 범위에서 제외됐고 Oracle은 같은 목표를 &lt;strong&gt;Project Leyden&lt;/strong&gt;으로 가져갔습니다. 기술이 죽은 건 아니지만 &amp;ldquo;중간 지대&amp;quot;였던 Graal JIT은 실제로 사라졌습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;Native Image가 C2보다 빠르다&amp;quot;는 유료 전제 위에 서 있습니다.&lt;/strong&gt; Oracle의 Petclinic 수치(13,075 vs 12,488 req/s)는 PGO와 G1을 켠 조합인데 &lt;strong&gt;둘 다 Community Edition에는 빠져 있습니다.&lt;/strong&gt; CE + Serial GC + PGO 없음이라는 실제 오픈소스 조합의 공개 수치는 어느 벤더 자료에도 없습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CE Native Image는 Serial GC 고정입니다.&lt;/strong&gt; 기본 최대 힙이 물리 메모리의 &lt;strong&gt;80%&lt;/strong&gt;(G1은 25%)이고 문서가 &amp;ldquo;GC 중 RSS가 최대 힙의 2배까지 일시 증가할 수 있어 컨테이너에서 문제가 된다&amp;quot;고 직접 경고합니다. &lt;code&gt;-Xmx&lt;/code&gt;를 지정하지 않으면 컨테이너에서 터집니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;동시성 논쟁의 실제 변수는 실행 모델이 아니라 acceptor입니다.&lt;/strong&gt; 6만 연결 실측에서 Tomcat은 CPU 20%인 채로 2만에서 99.9% 실패했습니다. TCP 연결을 받아들이는 쪽이 먼저 막혔고 처리 능력은 남아 있었습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;리액티브가 메모리에 유리하다는 통념은 조건부입니다.&lt;/strong&gt; 같은 실측에서 1.6KB 응답으로 바꾸자 WebFlux는 GC에 108초를 쓰며 P50이 1.17초로 무너졌고 가상 스레드가 31% 더 처리했습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;시동만 문제라면 런타임을 안 바꾸는 답이 생겼습니다.&lt;/strong&gt; JDK 24/25의 AOT 캐시는 Spring PetClinic 시동을 4.486초에서 2.604초로 줄이면서(&lt;strong&gt;42%&lt;/strong&gt;) JIT을 그대로 둡니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;회사에서 런타임을 바꿔보자는 말이 나오는 이유는 대개 비슷합니다. 시동이 느리다, 메모리를 많이 먹는다, 오토스케일이 붙을 때마다 처음 몇 초가 아프다. 그래서 GraalVM을 꺼내 봅니다.&lt;/p&gt;</description></item><item><title>Python 워커 16개 vs 워커 2 + 스레드 32</title><link>https://docs.makgol.com/runtime/02-python-worker-thread/</link><pubDate>Sat, 29 Aug 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/runtime/02-python-worker-thread/</guid><description>
&lt;h1&gt;02 · 워커 16개 vs 워커 2개 + 스레드 32개 — 무엇이 정말 달라지나&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--threads 32&lt;/code&gt;를 주는 순간 워커 클래스가 통째로 바뀝니다.&lt;/strong&gt; gunicorn 문서가 명시합니다 — &amp;ldquo;If you try to use the &lt;code&gt;sync&lt;/code&gt; worker type and set the &lt;code&gt;threads&lt;/code&gt; setting to more than 1, the &lt;code&gt;gthread&lt;/code&gt; worker type will be used instead.&amp;rdquo; &amp;ldquo;동기 워커에 스레드를 붙였다&amp;quot;는 표현부터 성립하지 않습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;최대 처리량은 거의 같습니다.&lt;/strong&gt; 같은 CPU limit 아래에서 두 배치의 상한은 둘 다 &lt;code&gt;limit ÷ 요청당 CPU 시간&lt;/code&gt;입니다. 달라지는 건 그 상한에 &lt;strong&gt;어떻게&lt;/strong&gt; 도달하는지, 상한을 넘긴 부하가 &lt;strong&gt;어디에 쌓이는지&lt;/strong&gt;입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;스레드 32개가 실제로 겹치는 건 GIL을 놓는 구간뿐입니다.&lt;/strong&gt; DB 대기와 외부 HTTP는 GIL 밖이고 ORM이 행을 객체로 바꾸는 순간부터 직렬화·템플릿까지는 전부 GIL 안입니다. 그래서 이득은 &lt;strong&gt;요청 시간에서 대기가 차지하는 비중&lt;/strong&gt;에 정비례합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--timeout&lt;/code&gt;의 의미가 달라집니다.&lt;/strong&gt; 동기 워커에서는 사실상 요청 상한이지만 gthread에서는 &amp;ldquo;프로세스가 살아 있다&amp;quot;는 신호일 뿐입니다. 옮겨 심지 않으면 요청 상한이 사라집니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;느린 요청 하나가 그 워커의 후속을 막는다&amp;quot;는 서술은 기본 설정에서 틀렸습니다.&lt;/strong&gt; 커널 accept 큐가 하나라 워커에 미리 배정된 후속 요청이 없습니다. 오히려 gthread가 커넥션을 미리 집어가면서 그 한 줄을 워커 수만큼 쪼갭니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;장애 반경이 16배 차이 납니다.&lt;/strong&gt; 워커 하나가 죽을 때 잃는 것은 (A)에서 요청 1개, (B)에서 최대 32개 + 그 워커가 물고 있던 keep-alive 커넥션 전부입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;스레드는 동시성을 늘리지 durability를 만들지 않습니다.&lt;/strong&gt; Celery의 대체재가 아닙니다. 순서가 반대입니다 — Celery로 무거운 작업을 빼야 (B)가 유리해지는 조건이 만들어집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;같은 파드, 같은 CPU limit에서 두 배치를 놓고 고민하는 상황입니다.&lt;/p&gt;</description></item><item><title>문제의 형태 — API Gateway를 떠나는 진짜 이유</title><link>https://docs.makgol.com/gateway/01-problem-shape/</link><pubDate>Thu, 06 Aug 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/gateway/01-problem-shape/</guid><description>
&lt;h1&gt;01 · 문제의 형태 — API Gateway를 떠나는 진짜 이유&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Connection duration for WebSocket API: 2 hours&lt;/code&gt; · &lt;code&gt;Can be increased: No&lt;/code&gt;. 이 전환의 유일한 논거입니다. 상시 연결이 전제인 단말에 2시간마다 강제 종료가 걸립니다.&lt;/li&gt;
&lt;li&gt;비용 논거는 성립하지 않습니다. 5만 대 상시 연결의 connection-minutes는 월 $540입니다. &amp;ldquo;비싸서 나간다&amp;quot;고 쓰면 첫 질문에서 무너집니다. &lt;em&gt;싸지만 맞지 않습니다.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;2시간 종료의 비용은 쿼터에서 나오지 않습니다. 재접속률 자체는 초당 7건으로 500/s 쿼터의 1.4%에 불과합니다. 재개 메커니즘이 없으면 2시간마다 5만 대가 전량 재동기화합니다. 그게 실제 비용입니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Idle Connection Timeout: 10 minutes&lt;/code&gt;도 상향 불가라 하트비트를 뺄 선택지가 없습니다. 자체 구현으로 옮겨도 이 제약은 없어지지 않고 LB idle timeout으로 이름만 바뀝니다.&lt;/li&gt;
&lt;li&gt;프레임 32KB / 페이로드 128KB. 초과하면 에러 응답 대신 close code 1009로 연결이 끊깁니다. 페이로드가 자랄 여지가 있으면 이 상한에 언제 걸릴지 알 수 없습니다.&lt;/li&gt;
&lt;li&gt;흐름이 일방향이면 WebSocket의 양방향성은 안 쓰는 기능입니다. SSE로 내려가면 재연결과 재개(&lt;code&gt;Last-Event-ID&lt;/code&gt;)가 프로토콜에 내장되어 따라옵니다. WebSocket에서는 전부 직접 만들어야 하는 것들입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;왜 이 문서인가. 전환 검토서의 첫 문장이 &amp;ldquo;API Gateway가 비싸서&amp;quot;이면 그 검토는 거기서 끝납니다. 실제로 계산해보면 쌉니다. 이 문서는 떠나야 하는 이유를 하나로 좁히고 자체 구현으로 넘어갔을 때 &lt;em&gt;따라오는 제약&lt;/em&gt;과 &lt;em&gt;없어지는 제약&lt;/em&gt;을 구분합니다. 검증 기준: AWS 공식 쿼터 표, API Gateway 요금표, WHATWG HTML 명세의 server-sent events 절.&lt;/p&gt;</description></item><item><title>수립 방향이라는 분기점</title><link>https://docs.makgol.com/gateway/02-connect-direction/</link><pubDate>Thu, 06 Aug 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/gateway/02-connect-direction/</guid><description>
&lt;h1&gt;02 · 수립 방향이라는 분기점&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&amp;ldquo;연결을 누가 거느냐&amp;quot;와 &amp;ldquo;데이터가 어디로 흐르느냐&amp;quot;는 별개입니다.&lt;/strong&gt; 중앙 → 단말 일방 푸시라는 요구는 두 분기가 모두 만족합니다. SSE·WebSocket·long-polling이 존재하는 이유 자체가 &lt;strong&gt;클라이언트가 건 연결 위에서 서버가 일방적으로 미는 것&lt;/strong&gt;이기 때문입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;현행 구성이 이미 답을 알고 있습니다.&lt;/strong&gt; API Gateway WebSocket API에는 &lt;strong&gt;클라이언트 개시 외의 모드가 없습니다.&lt;/strong&gt; 지금 돌아간다면 POS가 outbound로 걸고 있다는 뜻입니다 — 서비스 제약이 그것 말고는 허용하지 않습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;판정은 액세스 로그 한 줄이면 끝납니다.&lt;/strong&gt; &lt;code&gt;$context.identity.sourceIp&lt;/code&gt;가 매장 회선의 NAT 공인 IP로 찍히면 분기 A가 확정됩니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;분기는 링의 유무 말고도 여럿을 바꿉니다.&lt;/strong&gt; 전송 프로토콜(SSE가 맞는가), k8s 워크로드 종류(Deployment냐 StatefulSet이냐), 장애 감지 주체가 전부 뒤집힙니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;분기 B가 네트워크상 가능해도 보통은 A를 택합니다.&lt;/strong&gt; 5만 대의 주소 인벤토리, 단말별 TLS 서버 인증서와 그 갱신, 매장 방화벽 인바운드 규칙이 전부 새 운영 비용으로 붙기 때문입니다. &lt;strong&gt;B는 &amp;ldquo;가능한가&amp;quot;가 아니라 &amp;ldquo;그 값을 치를 만한가&amp;quot;로 판정해야 합니다.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;혼재는 A로 수렴시킵니다.&lt;/strong&gt; 일부 매장이 전용망이라 해서 두 경로를 함께 유지하면 장애 모드가 두 배가 됩니다. 전용망 매장도 outbound로 걸게 하면 A 하나로 끝납니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;왜 이 문서인가.&lt;/strong&gt; 이 질문 하나가 &lt;a href="https://docs.makgol.com/gateway/04-branch-a-client-dials/"&gt;04&lt;/a&gt;와 &lt;a href="https://docs.makgol.com/gateway/05-branch-b-pod-dials/"&gt;05&lt;/a&gt; 중 어느 쪽을 읽어야 하는지를 정합니다. 그런데 실무에서는 이 질문이 &lt;strong&gt;&amp;ldquo;중앙에서 단말로 밀어야 하니 중앙이 연결을 걸어야 하는 것 아닌가&amp;rdquo;&lt;/strong&gt; 라는 형태로 자주 뒤섞입니다. 여기서는 두 방향을 분리하고 판정을 코드 한 줄 짜지 않고 끝내는 절차를 남깁니다.&lt;/p&gt;</description></item><item><title>플랫폼 선례 해부 — 그들은 왜 링을 쓰는가</title><link>https://docs.makgol.com/gateway/03-platform-precedents/</link><pubDate>Thu, 06 Aug 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/gateway/03-platform-precedents/</guid><description>
&lt;h1&gt;03 · 플랫폼 선례 해부 — 그들은 왜 링을 쓰는가&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;링을 쓰는 이유는 다섯 시스템이 전부 다릅니다. &amp;ldquo;분산 시스템이니까 링&amp;quot;은 이유가 못 됩니다. 각자 못 피한 제약 하나를 링으로 우회했을 뿐입니다. 그 제약이 우리에게 없으면 링도 필요 없습니다.&lt;/li&gt;
&lt;li&gt;Loki/Mimir ingester가 링을 쓰는 진짜 이유는 쿼리입니다. flush 전 chunk가 그 파드 메모리에만 있어서 querier가 그 파드를 찾아가야 합니다. 링은 &amp;ldquo;누가 갖고 있나&amp;quot;를 O(1)로 답하는 주소록이고 부하 분산은 부수 효과입니다.&lt;/li&gt;
&lt;li&gt;vmagent는 링을 쓰지 않습니다. &lt;code&gt;hash(target) % membersCount&lt;/code&gt;이고 &lt;code&gt;memberNum&lt;/code&gt;은 플래그로 고정됩니다. 멤버십을 알지 못하고 죽은 멤버의 몫을 아무도 인수하지 않습니다 — 대신 &lt;code&gt;replicationFactor&lt;/code&gt;로 미리 중복 스크랩해 덮습니다.&lt;/li&gt;
&lt;li&gt;Alloy는 반대를 택했습니다. consistent hashing으로 노드당 512 토큰을 돌리고 문서가 트레이드오프를 명시합니다 — hashmod는 &lt;em&gt;fully consistent&lt;/em&gt;지만 재분배가 전량이고 consistent hashing은 이동이 1/N이지만 &lt;em&gt;&lt;strong&gt;eventually consistent&lt;/strong&gt;&lt;/em&gt;입니다. &amp;ldquo;eventually&amp;quot;가 곧 일시적 중복 소유입니다. 이게 분기 B의 최대 위험입니다.&lt;/li&gt;
&lt;li&gt;Promtail은 분배 문제를 배치로 없앴습니다. DaemonSet으로 노드마다 하나 두면 &amp;ldquo;누가 무엇을 맡나&amp;quot;가 질문조차 되지 않습니다. 우리 분기 A에서는 로드밸런서가 이 역할을 합니다.&lt;/li&gt;
&lt;li&gt;Thanos compactor는 링을 안 쓰고 상호배제를 사람에게 떠넘깁니다. &lt;em&gt;&amp;ldquo;you need to ensure on your own that only a single Compactor is running against a single stream&amp;rdquo;&lt;/em&gt; — 링의 한계를 가장 정직하게 드러낸 문장입니다. 링은 배정을 나눌 뿐 상호배제를 보장하지 않습니다.&lt;/li&gt;
&lt;li&gt;판정 축은 셋입니다 — ① 휘발성 상태가 파드 메모리에 있는가, ② 죽은 멤버의 몫을 인수해야 하는가, ③ 중복 소유가 사고인가. 우리 워크로드는 ①에 아니오, ②는 분기에 따라, ③은 분기 B에서만 예입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;ldquo;Loki도 링을 쓰니 우리도 링&amp;quot;은 근거가 아닙니다. 이 문서는 다섯 시스템에서 링을 채택하게 만든 제약을 하나씩 뽑아내고 그 제약이 POS 게이트웨이에 있는지를 대조합니다. 미리 말해 두면 분기 A에는 다섯 개 중 어느 제약도 없습니다. 검증 기준은 각 프로젝트 공식 문서와 CLI 플래그 정의입니다.&lt;/p&gt;</description></item><item><title>분기 A — POS가 건다: 라우팅을 없애는 설계</title><link>https://docs.makgol.com/gateway/04-branch-a-client-dials/</link><pubDate>Thu, 06 Aug 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/gateway/04-branch-a-client-dials/</guid><description>
&lt;h1&gt;04 · 분기 A — POS가 건다: 라우팅을 없애는 설계&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;커넥션 레지스트리를 만들지 않습니다. push를 pull로 뒤집으면 &amp;ldquo;어느 파드가 이 단말을 들고 있나&amp;quot;라는 질문이 사라집니다. 발신 서비스는 스트림에 &lt;code&gt;XADD&lt;/code&gt;만 합니다. 파드는 자기 커넥션에 해당하는 것만 골라 흘립니다.&lt;/li&gt;
&lt;li&gt;Redis Stream ID를 SSE &lt;code&gt;id:&lt;/code&gt;에 그대로 싣습니다. 그러면 &lt;code&gt;Last-Event-ID&lt;/code&gt;가 곧 &lt;code&gt;XREAD&lt;/code&gt;의 시작점이 되고 재개 로직이 따로 필요하지 않습니다. ID 체계를 어떻게 잡느냐로 푸는 문제입니다.&lt;/li&gt;
&lt;li&gt;샤딩은 파드가 받는 양을 줄이지 않습니다. 파드가 랜덤 분산이면 모든 샤드를 구독하므로 파드당 수신량은 총 이벤트량 그대로입니다. 샤딩이 줄이는 건 Redis 노드당 송신량입니다. 둘을 섞어 말하면 용량 산정이 틀립니다.&lt;/li&gt;
&lt;li&gt;탈출 임계는 &lt;code&gt;R × S × P ≤ 예산&lt;/code&gt; 하나입니다. 파드를 늘리면 Redis 송신량도 선형으로 같이 오릅니다 — 스케일아웃이 백엔드 부하를 키우는 구조이므로 용량 계획에 반영해야 합니다.&lt;/li&gt;
&lt;li&gt;재개 창은 명시적 계약입니다. &lt;code&gt;XADD ... MINID ~&lt;/code&gt;로 스트림을 시간 기준으로 자르고 창을 벗어난 재접속은 정상 경로로 &lt;code&gt;event: resync&lt;/code&gt;를 받아 전체 재동기화합니다. 장시간 오프라인 매장은 상시 발생합니다.&lt;/li&gt;
&lt;li&gt;브로드캐스트를 별도 스트림에 두지 않습니다. ID 공간이 둘로 나뉘어 &lt;code&gt;Last-Event-ID&lt;/code&gt; 계약이 깨집니다. 발신 측에서 샤드마다 &lt;code&gt;XADD&lt;/code&gt;를 반복하는 편이 훨씬 쌉니다.&lt;/li&gt;
&lt;li&gt;at-least-once는 클라이언트 규약으로 만듭니다. POS가 처리를 끝낸 뒤에 last event ID를 갱신하면 중간에 끊겨도 그 이벤트가 재개 시 다시 옵니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://docs.makgol.com/gateway/02-connect-direction/"&gt;02&lt;/a&gt;가 분기 A로 판정되면 이 문서가 설계 전문입니다. 주장은 하나입니다 — 재개 보장을 요구한 대가로 얻은 &amp;ldquo;이벤트가 파드 밖에 있다&amp;quot;는 성질을 끝까지 활용하면 API Gateway가 대신 해주던 커넥션 레지스트리를 만들 필요가 아예 없어집니다. &lt;a href="https://docs.makgol.com/gateway/03-platform-precedents/"&gt;03&lt;/a&gt;의 판정 축 ①(파드 메모리의 휘발성 상태)이 &amp;ldquo;없음&amp;quot;이기 때문에 성립하는 설계입니다.&lt;/p&gt;</description></item><item><title>분기 B — pod가 건다: 링을 만들어야 하는 경우</title><link>https://docs.makgol.com/gateway/05-branch-b-pod-dials/</link><pubDate>Thu, 06 Aug 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/gateway/05-branch-b-pod-dials/</guid><description>
&lt;h1&gt;05 · 분기 B — pod가 건다: 링을 만들어야 하는 경우&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;먼저 &amp;ldquo;연결을 상시 유지해야 하나&amp;quot;부터 물어야 합니다. POS에 우리가 닿을 수 있다면 보낼 게 생겼을 때 아무 파드나 &lt;code&gt;POST&lt;/code&gt;하면 됩니다. 상시 연결을 유지하지 않기로 하면 링도 lease도 통째로 필요 없어집니다 — B의 링 요구는 상당 부분 스스로 만든 문제입니다.&lt;/li&gt;
&lt;li&gt;링만으로는 중복 다이얼을 못 막습니다. &lt;a href="https://grafana.com/docs/alloy/latest/configure/clustering/distribute-prometheus-scrape-load/"target="_blank" rel="noopener"&gt;Alloy 문서&lt;/a&gt;가 consistent hashing을 &lt;em&gt;eventually consistent&lt;/em&gt;라고 명시하고 &lt;a href="https://thanos.io/tip/components/compact.md/"target="_blank" rel="noopener"&gt;Thanos&lt;/a&gt;는 상호배제를 아예 운영자에게 떠넘깁니다. 링은 후보를 좁히고 소유는 lease가 확정합니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hash % membersCount&lt;/code&gt;(vmagent 방식)는 우리 요구와 맞지 않습니다. 그 방식은 멤버십을 모르는 대신 죽은 몫 인수를 포기합니다. &amp;ldquo;죽은 파드의 몫을 남은 파드가 주워간다&amp;quot;가 요구사항이면 처음부터 배제됩니다.&lt;/li&gt;
&lt;li&gt;참고 원형은 Loki가 아니라 Kafka consumer group입니다. 중복이 사고인 도메인에서 검증된 방식은 재배정 순간에 소유권 공백을 만들어 겹침을 원천 차단하는 쪽입니다. 잘 나누는 것만으로는 부족합니다.&lt;/li&gt;
&lt;li&gt;단말별 lease는 비쌉니다. 샤드별 lease로 내려야 합니다. 5만 개 키를 5초마다 갱신하면 초당 1만 명령입니다. 소유 단위를 샤드(64개)로 올리면 키가 64개가 되고 갱신 부하가 세 자릿수 줄어듭니다.&lt;/li&gt;
&lt;li&gt;lease TTL이 곧 최대 무연결 시간입니다. TTL 15초면 파드가 죽고 최대 15초간 그 단말들은 끊겨 있습니다. 줄이면 갱신 부하가 오릅니다 — 이 트레이드오프가 B의 SLO를 정합니다.&lt;/li&gt;
&lt;li&gt;B에서도 StatefulSet은 근거가 약합니다. ordinal이 필요한 건 &lt;code&gt;hash % N&lt;/code&gt; 방식뿐인데 그건 이미 배제됐습니다. 멤버십을 Redis나 EndpointSlice에서 읽으면 Deployment로 충분합니다.&lt;/li&gt;
&lt;li&gt;B를 택하면 SSE는 폐기됩니다. pod가 걸고 POS가 SSE를 서빙하면 데이터가 반대로 흐릅니다. 전송 프로토콜을 처음부터 다시 골라야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;왜 이 문서인가. &lt;a href="https://docs.makgol.com/gateway/02-connect-direction/"&gt;02&lt;/a&gt;가 분기 B로 판정됐을 때의 설계입니다. 그런데 이 문서의 절반은 B를 축소하는 데 씁니다 — 링과 lease와 멤버십 발견을 전부 만들기 전에 그게 정말 필요한지를 세 번 되묻습니다. &lt;a href="https://docs.makgol.com/gateway/03-platform-precedents/"&gt;03&lt;/a&gt;의 판정 축 ②(죽은 몫 인수)와 ③(중복 소유가 사고인가)이 둘 다 &amp;ldquo;예&amp;quot;일 때만 이 문서 전체가 필요합니다.&lt;/p&gt;</description></item><item><title>k8s 형태 판정 — Deployment로 끝나는 이유와 종료 설계</title><link>https://docs.makgol.com/gateway/06-k8s-shape/</link><pubDate>Thu, 06 Aug 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/gateway/06-k8s-shape/</guid><description>
&lt;h1&gt;06 · k8s 형태 판정 — Deployment로 끝나는 이유와 종료 설계&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;두 분기 모두 Deployment로 끝납니다.&lt;/strong&gt; StatefulSet이 주는 안정적 ordinal·네트워크 ID·PVC·순차 롤링 중 이 워크로드가 쓰는 것이 하나도 없습니다. Loki ingester가 StatefulSet인 이유는 WAL용 PVC인데, &lt;strong&gt;우리는 디스크에 아무것도 쓰지 않습니다.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;headless service는 분기 A에서 필요 없습니다.&lt;/strong&gt; 파드 간 직접 통신이 생기는 건 &lt;a href="https://docs.makgol.com/gateway/04-branch-a-client-dials/"&gt;04 §6&lt;/a&gt;의 레지스트리 방식으로 전환할 때뿐입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;terminationGracePeriodSeconds&lt;/code&gt; 기본 30초는 이 워크로드에 짧습니다.&lt;/strong&gt; 파드 하나가 2,500개 SSE 연결을 들고 있고 그 연결을 흩어서 끊어야 하므로 종료 절차가 분 단위입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSE의 &lt;code&gt;retry:&lt;/code&gt; 필드가 재접속 폭풍의 유일한 프로토콜 레벨 해법입니다.&lt;/strong&gt; 종료 직전에 커넥션마다 다른 값을 밀어넣으면 2,500대의 재접속이 원하는 창에 흩어집니다. WebSocket에는 등가물이 없습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;순서가 중요합니다&lt;/strong&gt; — readiness 실패 → LB 드레이닝 대기 → &lt;code&gt;retry:&lt;/code&gt; 배포 → 점진적 종료. 이 순서가 틀리면 방금 끊은 연결이 다시 이 파드로 꽂힙니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CPU는 이 워크로드의 HPA 지표로 최악입니다.&lt;/strong&gt; idle SSE 연결은 CPU를 거의 안 씁니다. &lt;strong&gt;파드당 활성 커넥션 수&lt;/strong&gt;를 커스텀 메트릭으로 쓰고 &lt;strong&gt;scale-in은 그 자체가 재접속을 유발하므로&lt;/strong&gt; 안정화 창을 길게 잡습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ALB idle timeout 기본 60초가 하트비트 주기를 정합니다.&lt;/strong&gt; API Gateway의 10분 제약이 사라지는 대신 이 값이 들어옵니다 — &lt;strong&gt;없어지는 게 아니라 이름이 바뀝니다.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;압축과 버퍼링을 꺼야 합니다.&lt;/strong&gt; 경로상 어디든 응답을 버퍼링하면 SSE는 &amp;ldquo;연결은 됐는데 아무것도 안 오는&amp;rdquo; 상태가 됩니다. 가장 흔한 SSE 사고입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;ldquo;StatefulSet이나 headless service로 정의해야 하나&amp;quot;라는 질문에 답하고 그보다 훨씬 자주 사고를 내는 &lt;strong&gt;종료 설계&lt;/strong&gt;를 다룹니다. 장수명 연결 게이트웨이에서 배포는 평시 최대 부하 이벤트입니다 — 아무것도 안 하면 배포할 때마다 5만 대가 동시에 재접속합니다.&lt;/p&gt;</description></item><item><title>Kotlin 구현 노트 — 무엇이 실제로 어려운가</title><link>https://docs.makgol.com/gateway/07-kotlin-notes/</link><pubDate>Thu, 06 Aug 2026 00:00:00 +0900</pubDate><guid>https://docs.makgol.com/gateway/07-kotlin-notes/</guid><description>
&lt;h1&gt;07 · Kotlin 구현 노트 — 무엇이 실제로 어려운가&lt;/h1&gt;&lt;div class="hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-blue-200 hx:bg-blue-100 hx:text-blue-900 hx:dark:border-blue-200/30 hx:dark:bg-blue-900/30 hx:dark:text-blue-200"&gt;
&lt;div class="hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2"&gt;&lt;svg height=1.2em class="hx:inline-block hx:align-middle" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"&gt;&lt;path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/&gt;&lt;/svg&gt;&lt;/div&gt;
&lt;div class="hx:w-full hx:min-w-0 hx:leading-7"&gt;
&lt;div class="hx:mt-6 hx:leading-7 hx:first:mt-0"&gt;&lt;ul&gt;
&lt;li&gt;런타임 선택은 성능 문제가 아닙니다. WebFlux·Ktor·(MVC + 가상 스레드) 셋 다 파드당 2,500 연결을 여유 있게 감당합니다. 차이는 백프레셔를 어떤 모델로 표현하느냐에서 생깁니다. 팀이 이미 쓰는 것을 고르는 게 대개 옳습니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;XREAD BLOCK&lt;/code&gt;은 커넥션을 독점합니다. Lettuce 문서가 명시하듯 &lt;em&gt;&amp;ldquo;the connection will no longer respond to any other commands until XREAD completes&amp;rdquo;&lt;/em&gt; — tail 전용 커넥션을 따로 잡아야 하고 일반 명령용 커넥션과 절대 섞으면 안 됩니다.&lt;/li&gt;
&lt;li&gt;한 번의 &lt;code&gt;XREAD&lt;/code&gt;로 64개 스트림을 전부 읽을 수 있습니다. 샤드마다 커넥션을 만들 필요가 없습니다 — 스트림 하나당 스레드 하나를 붙이는 순진한 구현이 이 설계에서 가장 흔한 낭비입니다.&lt;/li&gt;
&lt;li&gt;그런데 Redis Cluster에서는 그게 &lt;code&gt;CROSSSLOT&lt;/code&gt;으로 깨집니다. 해시 태그로 샤드를 슬롯 그룹에 묶어 그룹당 &lt;code&gt;XREAD&lt;/code&gt; 하나로 만들거나, Cluster 대신 인스턴스를 애플리케이션 레벨로 나누는 편이 단순합니다.&lt;/li&gt;
&lt;li&gt;느린 소비자가 이 시스템의 조용한 킬러입니다. POS 하나가 TCP 수신 버퍼를 비우지 않으면 그 커넥션의 큐가 무한히 자랍니다. 커넥션당 큐 상한과 초과 시 연결 종료가 없으면 힙이 샙니다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Sinks.Many&lt;/code&gt;든 &lt;code&gt;Channel&lt;/code&gt;이든 상한 없는 버퍼를 쓰지 마세요. 기본값이 무제한인 API가 많습니다.&lt;/li&gt;
&lt;li&gt;POS 클라이언트를 우리가 만든다는 사실이 설계 자산입니다. last event ID를 처리 완료 후에 커밋하게 하면 서버 코드 변경 없이 at-least-once가 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://docs.makgol.com/gateway/04-branch-a-client-dials/"&gt;04&lt;/a&gt;의 설계를 JVM/Kotlin으로 옮길 때 실제로 발목을 잡는 것들만 모았습니다. 프레임워크 튜토리얼이 다루지 않는 blocking 명령의 커넥션 독점, Cluster의 CROSSSLOT, 느린 소비자가 본론입니다.&lt;/p&gt;</description></item></channel></rss>