<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Service Discovery on jyukki's Blog</title><link>https://jyukki.com/tags/service-discovery/</link><description>Recent content in Service Discovery on jyukki's Blog</description><generator>Hugo -- 0.147.0</generator><language>ko-kr</language><lastBuildDate>Tue, 14 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://jyukki.com/tags/service-discovery/index.xml" rel="self" type="application/rss+xml"/><item><title>백엔드 커리큘럼 심화: Service Discovery와 Health-Aware Routing 실무 설계</title><link>https://jyukki.com/learning/deep-dive/deep-dive-service-discovery-health-aware-routing/</link><pubDate>Tue, 14 Apr 2026 00:00:00 +0000</pubDate><guid>https://jyukki.com/learning/deep-dive/deep-dive-service-discovery-health-aware-routing/</guid><description>인스턴스가 자주 바뀌는 환경에서 DNS, registry, client-side/server-side discovery, active/passive health check를 어떻게 조합해야 안정적인 라우팅이 되는지 실무 기준으로 정리합니다.</description><content:encoded><![CDATA[<p>서비스를 처음 만들 때는 discovery가 별문제가 아닙니다. URL 하나 고정해 두고 뒤에 서버 두세 대만 붙여도 대부분 돌아갑니다. 그런데 오토스케일링이 붙고, 배포가 하루 여러 번 일어나고, readiness가 늦게 올라오는 인스턴스가 생기기 시작하면 문제가 달라집니다. DNS에는 아직 살아 있다고 나오는데 실제로는 drain 중인 인스턴스로 붙고, registry는 healthy라고 표시하는데 애플리케이션 워밍업이 끝나지 않아 첫 요청 수십 개가 터지고, 장애 난 노드를 outlier ejection 없이 계속 재시도하다가 전체 지연이 번지는 식입니다.</p>
<p>실무에서 service discovery의 핵심은 &ldquo;어디에 붙을까&quot;보다 <strong>언제 붙으면 안 되는가를 얼마나 빨리 반영하느냐</strong>에 가깝습니다. 같은 서비스라도 DNS 기반이 맞는 경우가 있고, registry watch가 필요한 경우가 있고, client-side discovery보다 L7 프록시나 service mesh가 훨씬 안전한 경우도 있습니다. 결국 discovery는 주소 찾기 기능이 아니라 <strong>신선도(freshness), 실패 격리, 운영 일관성 사이의 균형 문제</strong>입니다.</p>
<p>이 글은 service discovery를 추상 개념으로 끝내지 않고, 어떤 팀에서 DNS만으로 충분한지, 언제 registry 또는 mesh로 넘어가야 하는지, health-aware routing에서 어떤 숫자를 기본값으로 잡아야 하는지 정리합니다. 같이 보면 좋은 글로는 <a href="/learning/deep-dive/deep-dive-api-gateway-design/">API Gateway 설계</a>, <a href="/learning/deep-dive/deep-dive-load-balancer-healthchecks/">Load Balancer Health Check</a>, <a href="/learning/deep-dive/deep-dive-dns-internals/">DNS Internals</a>, <a href="/learning/deep-dive/deep-dive-service-mesh-istio/">Service Mesh Istio</a>가 있습니다.</p>
<h2 id="이-글에서-얻는-것">이 글에서 얻는 것</h2>
<ul>
<li>service discovery를 DNS, registry, service mesh 관점에서 비교하고 현재 환경에 맞는 기본값을 정할 수 있습니다.</li>
<li>liveness, readiness, passive check를 어떻게 나눠야 실제 장애 전파를 줄일 수 있는지 실무 기준을 잡을 수 있습니다.</li>
<li>stale endpoint, connection draining 누락, zone 불균형 같은 운영 사고를 어떤 순서로 막아야 하는지 판단 기준을 세울 수 있습니다.</li>
</ul>
<h2 id="핵심-개념이슈">핵심 개념/이슈</h2>
<h3 id="1-discovery의-본질은-주소-조회가-아니라-신선도-예산-관리다">1) discovery의 본질은 주소 조회가 아니라 &ldquo;신선도 예산&rdquo; 관리다</h3>
<p>많은 글이 service discovery를 &ldquo;서비스 이름을 실제 IP로 바꾸는 메커니즘&quot;이라고 설명합니다. 틀린 말은 아니지만 운영에서는 이 설명만으로 부족합니다. 더 중요한 질문은 아래입니다.</p>
<ul>
<li>인스턴스가 죽거나 drain되면 <strong>몇 초 안에</strong> 라우팅 테이블에서 빠져야 하는가</li>
<li>새 인스턴스가 뜨면 <strong>언제부터</strong> 실제 트래픽을 받아도 되는가</li>
<li>부분 장애가 생겼을 때 잘못된 endpoint 정보가 <strong>얼마나 넓게</strong> 퍼질 수 있는가</li>
</ul>
<p>예를 들어 배포 간격이 하루 1회이고 인스턴스 변화가 거의 없다면 DNS TTL 30초도 크게 문제되지 않을 수 있습니다. 반대로 10분마다 scale in/out이 일어나고 rolling update 중 warm-up이 20초 걸리는 시스템이면 DNS TTL 30초는 너무 깁니다. 오래된 레코드가 남아 있어도 사용자 요청은 계속 그쪽으로 갑니다.</p>
<p>그래서 discovery 설계는 보통 아래 세 축으로 봐야 맞습니다.</p>
<ul>
<li><strong>신선도</strong>: endpoint 변화가 라우팅에 반영되는 속도</li>
<li><strong>일관성</strong>: 모든 클라이언트가 비슷한 뷰를 보는 정도</li>
<li><strong>폭발 반경</strong>: 잘못된 상태가 퍼졌을 때 몇 개 클라이언트가 동시에 영향받는가</li>
</ul>
<p>이 관점이 없으면 &ldquo;Consul이 좋나, DNS가 좋나&rdquo; 같은 도구 비교로 끝나기 쉽습니다. 실제로는 도구보다 <strong>업데이트 빈도와 실패 비용</strong>이 먼저입니다.</p>
<h3 id="2-dns-registry-mesh는-대체재가-아니라-운영-단계별-기본값이다">2) DNS, registry, mesh는 대체재가 아니라 운영 단계별 기본값이다</h3>
<p>세 가지를 단순 비교하면 아래 정도로 정리할 수 있습니다.</p>
<table>
  <thead>
      <tr>
          <th>방식</th>
          <th>장점</th>
          <th>약점</th>
          <th>잘 맞는 환경</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>DNS 기반 discovery</strong></td>
          <td>단순함, 표준성, 운영 비용 낮음</td>
          <td>TTL 때문에 stale endpoint 가능</td>
          <td>인스턴스 변화가 느린 내부 서비스</td>
      </tr>
      <tr>
          <td><strong>Registry 기반 discovery</strong></td>
          <td>빠른 갱신, metadata 풍부</td>
          <td>클라이언트 라이브러리/운영 복잡도 증가</td>
          <td>VM/ECS, 빠른 오토스케일링</td>
      </tr>
      <tr>
          <td><strong>Proxy/Mesh 기반 routing</strong></td>
          <td>재시도, outlier ejection, mTLS 일관화</td>
          <td>학습비용과 운영면 복잡</td>
          <td>polyglot, 대규모 마이크로서비스</td>
      </tr>
  </tbody>
</table>
<p>Kubernetes 안에서는 Service + EndpointSlice + readiness probe만으로도 꽤 많은 문제를 해결합니다. 이 경우 discovery 자체를 애플리케이션이 직접 다루기보다 플랫폼이 처리하는 편이 안전합니다. 반대로 VM 기반 서비스나 여러 런타임이 섞인 환경에서는 registry가 더 직접적일 수 있습니다. 중요한 것은 <strong>&ldquo;더 최신 기술&quot;이 아니라 팀이 감당할 수 있는 운영면을 고르는 것</strong>입니다.</p>
<p>실무 기준으로는 아래처럼 출발하는 편이 무난합니다.</p>
<ul>
<li>단일 클러스터, 동일 플랫폼, 서비스 30개 이하: DNS 또는 플랫폼 기본 Service 우선</li>
<li>scale event가 10분 내 20% 이상 자주 발생: registry watch 또는 proxy 갱신 도입 검토</li>
<li>언어/프레임워크가 4종 이상, 재시도 정책이 제각각: server-side proxy 또는 mesh 우선</li>
<li>보안, mTLS, traffic policy를 팀별 코드에 맡기기 어렵다: mesh 또는 공용 프록시 우선</li>
</ul>
<p>즉 discovery는 중앙집중화할수록 일관성이 좋아지고, 단순화할수록 장애 면적은 작아집니다. 어느 쪽이 더 좋은지가 아니라 어느 비용을 지금 감당할 수 있는지가 중요합니다.</p>
<h3 id="3-client-side-discovery는-빠르지만-정책-드리프트-비용을-꼭-같이-계산해야-한다">3) client-side discovery는 빠르지만, 정책 드리프트 비용을 꼭 같이 계산해야 한다</h3>
<p>client-side discovery의 장점은 명확합니다. 클라이언트가 registry나 endpoint 목록을 직접 보고, 로컬에서 로드밸런싱을 결정하므로 홉이 줄고 유연성이 높습니다. 하지만 언어가 늘고 서비스 수가 늘어나면 다른 비용이 바로 올라옵니다.</p>
<ul>
<li>재시도, 타임아웃, outlier ejection 정책이 서비스마다 달라짐</li>
<li>같은 장애를 만나도 Java, Go, Node 클라이언트의 행동이 달라짐</li>
<li>discovery 라이브러리 버전 차이로 stale endpoint 처리 방식이 갈림</li>
<li>관측 포인트가 분산돼서 운영자가 공통 룰을 적용하기 어려움</li>
</ul>
<p>그래서 client-side discovery는 보통 아래 조건을 만족할 때만 권장할 만합니다.</p>
<ul>
<li>주요 서비스가 1~2개 언어로 제한돼 있다.</li>
<li>플랫폼 팀이 공통 SDK를 실제로 유지보수할 수 있다.</li>
<li>지연 예산이 매우 빡빡해서 프록시 홉 1개도 아쉬운 구간이다.</li>
<li>서비스별 라우팅 로직 차별화가 비즈니스적으로 중요하다.</li>
</ul>
<p>그 외에는 server-side discovery가 더 안정적입니다. 프록시, API gateway, service mesh를 거치면 홉은 늘지만, health check, retry, circuit breaking, drain 정책을 한 곳에서 고정하기 쉬워집니다. <a href="/learning/deep-dive/deep-dive-api-gateway-design/">API Gateway 설계</a>나 <a href="/learning/deep-dive/deep-dive-service-mesh-istio/">Service Mesh Istio</a>를 실제로 운영해 보면, 성능 최적화보다 <strong>정책 일관성</strong>이 더 큰 이득일 때가 많습니다.</p>
<h3 id="4-health-aware-routing에서-가장-흔한-실수는-liveness와-readiness를-섞는-것이다">4) health-aware routing에서 가장 흔한 실수는 liveness와 readiness를 섞는 것이다</h3>
<p>실무 장애의 절반 이상은 &ldquo;죽은 인스턴스&quot;보다 &ldquo;살아는 있지만 아직 받을 준비가 안 된 인스턴스&rdquo; 때문에 납니다. 그래서 health check는 최소한 세 층으로 나눠 생각해야 합니다.</p>
<ol>
<li><strong>liveness</strong>: 프로세스가 죽었는가, hang 상태인가</li>
<li><strong>readiness</strong>: 지금 신규 요청을 받아도 되는가</li>
<li><strong>passive health</strong>: 실제 요청 실패율과 지연이 나빠졌는가</li>
</ol>
<p>liveness를 readiness처럼 쓰면 워밍업 중 인스턴스가 너무 빨리 트래픽을 받습니다. 반대로 readiness에 외부 의존성을 과하게 넣으면 DB가 잠깐 느려졌다고 healthy 인스턴스가 한꺼번에 빠지는 문제도 생깁니다.</p>
<p>권장 기본값은 아래 정도입니다.</p>
<ul>
<li>readiness probe 주기: <strong>5초</strong></li>
<li>unhealthy threshold: <strong>2~3회 연속 실패</strong></li>
<li>success threshold: <strong>2회 연속 성공</strong></li>
<li>startup grace period: <strong>15~60초</strong>, 실제 warm-up 시간에 맞춤</li>
<li>connection draining: <strong>30~90초</strong>, longest in-flight request보다 길게</li>
</ul>
<p>여기서 핵심은 헬스체크가 빠르기만 하면 되는 것이 아니라, <strong>flap을 만들지 않으면서도 stale endpoint 체류 시간을 줄여야 한다</strong>는 점입니다. <a href="/learning/deep-dive/deep-dive-load-balancer-healthchecks/">Load Balancer Health Check</a>를 보면 active check만으로는 놓치는 경우가 많고, 실제 요청 실패를 반영하는 passive signal이 같이 있어야 outlier ejection 품질이 좋아집니다.</p>
<h3 id="5-stale-endpoint보다-더-위험한-것은-drain되지-않는-연결이다">5) stale endpoint보다 더 위험한 것은 drain되지 않는 연결이다</h3>
<p>많은 팀이 endpoint 제거만 신경 쓰고 기존 연결을 잊습니다. 그런데 실제 사고는 이미 붙어 있던 keep-alive connection이 drain 중인 인스턴스로 계속 가면서 생깁니다. registry에서 unhealthy로 빠졌더라도 아래가 남아 있으면 사용자 입장에서는 계속 실패가 납니다.</p>
<ul>
<li>장수 커넥션 풀에 남은 오래된 upstream 연결</li>
<li>HTTP/2 멀티플렉싱으로 유지되는 기존 세션</li>
<li>클라이언트 DNS cache 또는 JVM DNS cache</li>
<li>애플리케이션 레벨의 자체 endpoint memoization</li>
</ul>
<p>그래서 health-aware routing은 등록/해제만이 아니라 <strong>draining, max connection age, idle timeout, connection pool refresh</strong>를 같이 다뤄야 완성됩니다. 예를 들어 rolling update 중 60초 drain을 걸어도 클라이언트 커넥션 최대 수명이 10분이면 의도한 효과가 안 나옵니다.</p>
<p>실무에서는 아래 기준을 많이 씁니다.</p>
<ul>
<li>connection max age: <strong>2~5분</strong></li>
<li>idle timeout: <strong>30~120초</strong></li>
<li>deploy preStop + drain: <strong>30초 이상</strong></li>
<li>outlier ejection: 최근 <strong>30초</strong> 창에서 5xx 또는 timeout 비율 기준 적용</li>
</ul>
<p>이 값은 서비스마다 달라지지만, 공통 원칙은 같습니다. <strong>endpoint 생명주기와 connection 생명주기를 분리해서 보면 안 됩니다.</strong></p>
<h3 id="6-zone-aware-routing과-outlier-ejection이-없으면-부분-장애가-전체-장애처럼-번진다">6) zone aware routing과 outlier ejection이 없으면 부분 장애가 전체 장애처럼 번진다</h3>
<p>서비스 discovery가 잘 돼도 라우팅 정책이 단순 라운드로빈이면, 특정 가용영역이나 특정 노드풀의 문제가 전체로 번질 수 있습니다. 특히 cross-zone 비용을 줄이려 local zone 우선 라우팅을 쓰는 환경에서는, 한 zone 안의 이상 노드를 빨리 잘라내는 장치가 더 중요합니다.</p>
<p>권장 순서는 보통 이렇습니다.</p>
<ul>
<li>1차: 같은 zone 우선 라우팅</li>
<li>2차: passive failure rate 기반 outlier ejection</li>
<li>3차: concurrency limit과 circuit breaker로 전파 차단</li>
<li>4차: zone 전체가 나쁘면 cross-zone failover 허용</li>
</ul>
<p>이 순서가 중요한 이유는, discovery만으로는 &ldquo;어디가 살아 있는가&quot;까지만 알 수 있고 &ldquo;지금 어디가 덜 나쁜가&quot;는 못 알기 때문입니다. 부분 장애가 생기면 정적 discovery보다 동적 routing signal이 더 중요해집니다. 이 판단은 <a href="/learning/deep-dive/deep-dive-priority-load-shedding-bulkhead/">Circuit Breaker와 Bulkhead</a>나 <a href="/learning/deep-dive/deep-dive-tail-latency-engineering-playbook/">Tail Latency 엔지니어링</a>과도 연결됩니다.</p>
<h2 id="실무-적용">실무 적용</h2>
<h3 id="1-환경별-권장-기본-아키텍처">1) 환경별 권장 기본 아키텍처</h3>
<p><strong>작은 팀, Kubernetes 내부 서비스 중심</strong></p>
<ul>
<li>Service DNS + readiness probe + preStop drain을 기본값으로 둡니다.</li>
<li>애플리케이션에서 discovery 라이브러리를 직접 붙이기보다 플랫폼 기본을 믿는 편이 운영 비용이 낮습니다.</li>
<li>이 단계에서는 복잡한 mesh보다 health check 품질과 timeout 정리가 먼저입니다.</li>
</ul>
<p><strong>VM/ECS 혼합, scale event가 잦은 환경</strong></p>
<ul>
<li>registry 기반 endpoint 갱신과 공용 L7 프록시를 우선 검토합니다.</li>
<li>각 서비스에 client-side discovery를 흩뿌리기보다, 공통 프록시에서 retry/outlier 정책을 고정하는 편이 장애 대응이 쉽습니다.</li>
</ul>
<p><strong>polyglot, 보안 정책 강함, 서비스 수 100개 이상</strong></p>
<ul>
<li>mesh 또는 sidecar 기반으로 health-aware routing을 중앙 정책화하는 편이 낫습니다.</li>
<li>이때도 모든 기능을 한 번에 켜지 말고, mTLS, retry, outlier ejection, zone routing 순으로 단계적으로 여는 것이 안전합니다.</li>
</ul>
<h3 id="2-의사결정-기준숫자조건우선순위">2) 의사결정 기준(숫자·조건·우선순위)</h3>
<p>실무 우선순위는 보통 <strong>잘못된 endpoint 제거 속도 &gt; drain 일관성 &gt; 라우팅 정책 표준화 &gt; 홉 최적화</strong> 순으로 잡는 편이 사고를 줄입니다.</p>
<p>권장 시작 기준은 아래 정도입니다.</p>
<ol>
<li><strong>신선도 기준</strong>
<ul>
<li>autoscale 또는 배포로 endpoint가 <strong>10분 내 20% 이상</strong> 자주 바뀌면 DNS only 구조를 재검토</li>
<li>잘못된 endpoint 체류 시간이 <strong>15초 초과</strong>하면 registry watch 또는 더 짧은 readiness/deregistration 경로 검토</li>
</ul>
</li>
<li><strong>헬스체크 기준</strong>
<ul>
<li>신규 인스턴스 warm-up이 <strong>20초 이상</strong> 걸리면 readiness와 startup probe 분리</li>
<li>false positive로 healthy 인스턴스가 한 번에 <strong>5% 이상</strong> 빠지면 probe 조건 단순화 또는 threshold 상향</li>
</ul>
</li>
<li><strong>라우팅 기준</strong>
<ul>
<li>한 zone 장애 시 전체 에러율이 <strong>2배 이상</strong> 튀면 zone aware routing 우선 적용</li>
<li>partial failure 구간에서 retry amplification ratio가 <strong>1.3 이상</strong>이면 retry보다 outlier ejection 먼저 손봄</li>
</ul>
</li>
<li><strong>운영 기준</strong>
<ul>
<li>서비스별 discovery 라이브러리 종류가 <strong>3개 이상</strong>이면 중앙 프록시 또는 공통 SDK 표준화 검토</li>
<li>배포 중 stale connection 관련 에러가 주간 <strong>2회 이상</strong> 나오면 drain, pool refresh, max age를 같은 변경 세트로 묶어 개선</li>
</ul>
</li>
</ol>
<h3 id="3-장애-대응-런북">3) 장애 대응 런북</h3>
<p>운영에서 discovery 사고가 났을 때는 아래 순서가 효율적입니다.</p>
<p><strong>1단계, 정보 신선도 확인</strong><br>
registry, DNS, EndpointSlice, 프록시 upstream view가 서로 같은지 비교합니다. 여기서 서로 다르면 stale 정보 문제일 가능성이 큽니다.</p>
<p><strong>2단계, readiness와 실제 실패 지표 비교</strong><br>
healthy로 보이는데 timeout/5xx가 높다면 readiness가 너무 낙관적이거나 passive health가 빠져 있을 수 있습니다.</p>
<p><strong>3단계, drain 경로 확인</strong><br>
배포 직후만 에러가 늘었다면 preStop, connection draining, keep-alive max age를 먼저 봅니다.</p>
<p><strong>4단계, retry 증폭 차단</strong><br>
부분 장애에서 재시도는 쉽게 전체 장애를 만듭니다. retry budget과 timeout을 임시로 줄여 증폭을 먼저 꺼야 합니다.</p>
<p>이 순서를 지키면 원인 파악이 빨라집니다. discovery 사고는 대부분 &ldquo;도구 하나가 나빠서&quot;가 아니라 <strong>상태 반영 경로가 여러 계층에서 어긋난 결과</strong>이기 때문입니다.</p>
<h2 id="트레이드오프주의점">트레이드오프/주의점</h2>
<ol>
<li>
<p><strong>TTL을 너무 짧게 잡으면 DNS, registry, control plane 부하가 올라갑니다.</strong><br>
신선도는 좋아지지만 전체 시스템이 더 자주 흔들릴 수 있습니다.</p>
</li>
<li>
<p><strong>client-side discovery는 빠르지만 표준화 실패 시 팀별 동작 차이가 커집니다.</strong><br>
처음에는 간단해 보여도, 시간이 지나면 운영자가 가장 싫어하는 구조가 되기 쉽습니다.</p>
</li>
<li>
<p><strong>health check를 너무 공격적으로 잡으면 flap이 생깁니다.</strong><br>
짧은 순간의 GC, 네트워크 스파이크, cold start 때문에 healthy 인스턴스가 쓸데없이 빠질 수 있습니다.</p>
</li>
<li>
<p><strong>mesh를 넣는다고 discovery 문제가 자동으로 해결되지는 않습니다.</strong><br>
readiness, drain, timeout, retry budget이 나쁘면 mesh는 복잡도만 더할 수도 있습니다.</p>
</li>
</ol>
<h2 id="체크리스트-또는-연습">체크리스트 또는 연습</h2>
<h3 id="체크리스트">체크리스트</h3>
<ul>
<li><input disabled="" type="checkbox"> liveness, readiness, passive health signal이 분리되어 있다.</li>
<li><input disabled="" type="checkbox"> endpoint 해제와 connection draining이 같은 배포 절차에 묶여 있다.</li>
<li><input disabled="" type="checkbox"> zone aware routing 또는 equivalent fallback 정책이 있다.</li>
<li><input disabled="" type="checkbox"> retry 정책보다 outlier ejection과 timeout 기준이 먼저 정리돼 있다.</li>
<li><input disabled="" type="checkbox"> stale endpoint 체류 시간과 drain 실패율을 숫자로 본다.</li>
</ul>
<h3 id="연습-과제">연습 과제</h3>
<ol>
<li>현재 서비스 하나를 골라 endpoint 변경이 실제 클라이언트 라우팅에 반영되기까지 몇 초 걸리는지 측정해 보세요. 15초를 넘는다면 어느 계층이 병목인지 바로 보일 가능성이 큽니다.</li>
<li>rolling update 중 에러가 나는 서비스가 있다면 preStop, readiness success threshold, connection max age를 한 화면에 정리해 보세요. 보통 세 값이 따로 놀고 있습니다.</li>
<li>client-side discovery를 쓰는 서비스 2개와 server-side proxy를 쓰는 서비스 2개를 비교해, 재시도/타임아웃/헬스체크 정책 차이가 얼마나 나는지 표로 적어 보세요. 차이가 크면 다음 장애 때 대응 속도도 달라집니다.</li>
</ol>
<h2 id="관련-글">관련 글</h2>
<ul>
<li><a href="/learning/deep-dive/deep-dive-api-gateway-design/">API Gateway 설계</a></li>
<li><a href="/learning/deep-dive/deep-dive-load-balancer-healthchecks/">Load Balancer Health Check</a></li>
<li><a href="/learning/deep-dive/deep-dive-dns-internals/">DNS Internals</a></li>
<li><a href="/learning/deep-dive/deep-dive-service-mesh-istio/">Service Mesh Istio</a></li>
<li><a href="/learning/deep-dive/deep-dive-priority-load-shedding-bulkhead/">Priority Load Shedding과 Bulkhead</a></li>
<li><a href="/learning/deep-dive/deep-dive-tail-latency-engineering-playbook/">Tail Latency 엔지니어링 플레이북</a></li>
</ul>
]]></content:encoded></item></channel></rss>