프롤로그 — "왜 HTTP/3는 UDP를 쓰는가? 왜 TLS 1.3은 1-RTT인가?"
2025년 4월, 당신의 REST API가 한국에서 200ms, 미국에서 800ms 걸린다.
- **원인 1**: TCP Handshake 1-RTT + TLS 1.2 Handshake 2-RTT = **3-RTT 오버헤드**
- **원인 2**: TCP Head-of-Line Blocking — 패킷 1개 손실 시 뒤 패킷 모두 대기
- **원인 3**: CDN 없이 Origin에서 직접 서빙
- **해결**: HTTP/3 + QUIC(0-RTT resumption) + Cloudflare Anycast → **200ms로 단축**
Database(Ep 13)가 영속 상태를 다뤘다면, 네트워크는 **상태를 옮기는 배관**이다.
2025년 네트워크는 **TCP에서 QUIC으로**, **REST에서 gRPC/tRPC로**, **Origin에서 Edge로** 이동 중이다.
Cloudflare는 Workers로 서버리스 엣지를, Fastly는 Compute@Edge로 WebAssembly를 민다.
이 글은 Season 2 Ep 14 — **네트워크**.
OSI 7계층부터 QUIC의 0-RTT, TLS 1.3 Handshake, gRPC Streaming, WebSocket 재연결 패턴, CDN Cache Invalidation까지.
"패킷이 어디로 가는지"를 알면 디버깅이 달라진다.
1부 — OSI 7계층과 TCP/IP 4계층
OSI 7계층 (이론) vs TCP/IP 4계층 (실전)
| OSI | TCP/IP | 예시 |
|---|---|---|
| 7. Application | Application | HTTP, gRPC, DNS |
| 6. Presentation | Application | TLS, JSON |
| 5. Session | Application | WebSocket |
| 4. Transport | Transport | TCP, UDP, QUIC |
| 3. Network | Internet | IP, ICMP |
| 2. Data Link | Link | Ethernet, WiFi |
| 1. Physical | Link | 광섬유, 구리선 |
실전에서는 **TCP/IP 4계층**이면 충분. OSI는 학술/인터뷰용.
패킷이 브라우저에서 서버까지 가는 길 (2025)
1. DNS lookup: api.example.com → 1.2.3.4 (UDP:53, DoH/DoT로 암호화 추세)
2. TCP Handshake: SYN → SYN-ACK → ACK (1-RTT)
(또는 QUIC: Initial → Handshake → 1-RTT 데이터, 0-RTT resumption 가능)
3. TLS Handshake: ClientHello → ServerHello → Finished (TLS 1.3: 1-RTT)
4. HTTP Request: GET /api/users HTTP/2
5. 서버 처리 + DB 쿼리
6. HTTP Response: 200 OK + JSON
7. TCP Close: FIN → ACK → FIN → ACK (4-way)
**총 왕복**: TCP+TLS 1.2 = **3-RTT**, QUIC+TLS 1.3 = **1-RTT**, QUIC 0-RTT resumption = **0-RTT**.
한국-미국 왕복 150ms 기준, TCP+TLS 1.2는 **450ms 대기**, QUIC 0-RTT는 **0ms 대기**.
2부 — TCP vs UDP vs QUIC
TCP — 신뢰성의 클래식
특징: 연결 지향, 신뢰성, 순서 보장, 혼잡 제어
Handshake: 3-way (SYN, SYN-ACK, ACK)
Window: Congestion + Flow Control
Retransmission: 패킷 손실 시 재전송
Ordering: sequence number로 순서 보장
**장점**: 안정적, OS 레벨 지원, 방화벽 통과 쉬움
**단점**:
- Handshake 1-RTT 오버헤드
- **Head-of-Line Blocking**: 패킷 1개 손실 시 뒤 패킷 모두 버퍼링
- Slow Start: 초기 대역폭 낮음
- 모바일 환경 취약 (IP 변경 시 재연결)
UDP — 최소주의 전송
특징: 비연결, 비신뢰, 순서 미보장
Handshake: 없음
Overhead: 8 bytes 헤더
Use cases: DNS, 게임, 영상 스트리밍, WebRTC, VoIP
**장점**: 빠름, 오버헤드 최소
**단점**: 애플리케이션이 신뢰성/순서 관리 책임
**2025 현실**: QUIC/HTTP/3의 기반, DNS over HTTPS(DoH)
QUIC — HTTP/3의 기반, 2025년 필수
2012년 Google이 SPDY의 한계를 극복하려 시작. 2021년 RFC 9000으로 표준화.
**"UDP 위에 TCP+TLS+HTTP/2를 재구현"** — 근데 더 빠르게.
QUIC = UDP + Reliability + Ordering + TLS 1.3 + Multiplexing + 0-RTT
**핵심 개선**:
1. **0-RTT Resumption**: 이전 세션 키로 첫 패킷에 데이터 포함
2. **Stream-level Multiplexing**: Stream 단위 HOL Blocking 제거 (TCP는 connection 단위)
3. **Connection Migration**: IP 변경되어도 Connection ID로 유지 (WiFi → LTE 전환 끊김 없음)
4. **Always-encrypted**: 패킷 메타데이터까지 암호화 (TLS 1.3 내장)
5. **User-space 구현**: 커널 업데이트 없이 배포 가능 (Chrome, Cloudflare가 push)
**어댑션 2025**: HTTPS 트래픽의 **30%가 HTTP/3/QUIC** (Cloudflare 기준).
- Google: 95%+ QUIC
- Meta: 75%+
- Cloudflare, Fastly: 기본 활성화
- 일반 CDN 고객: opt-in
TCP vs QUIC 벤치마크
| 시나리오 | TCP+TLS 1.2 | QUIC+TLS 1.3 | 개선율 |
|---|---|---|---|
| First load (Cold) | 450ms (3-RTT) | 150ms (1-RTT) | 3x |
| Repeat load (Warm) | 150ms (1-RTT) | 0ms (0-RTT) | ∞ |
| 3G with 5% loss | 2500ms | 800ms | 3x |
| WiFi → LTE 전환 | 재연결 | 무중단 | N/A |
3부 — HTTP/1.1 → HTTP/2 → HTTP/3 진화
HTTP/1.1 (1997) — 아직도 많이 쓰임
GET /users HTTP/1.1
Host: api.example.com
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 42
{"users": [{"id": 1, "name": "Alice"}]}
**장점**: 단순, 텍스트 기반, 디버깅 쉬움
**단점**:
- 1 connection = 1 request at a time (HOL)
- 브라우저가 도메인당 connection 6개로 제한 → "domain sharding" hack
- Header 중복 (매 요청마다 Cookie, User-Agent 전송)
**현재 쓰임**: Server-to-Server, 간단한 REST, 레거시
HTTP/2 (2015) — 바이너리 멀티플렉싱
특징:
- 바이너리 프레이밍 (텍스트 X)
- 1 connection에서 여러 stream 동시 전송 (Multiplexing)
- Header Compression (HPACK)
- Server Push (deprecated in 2022)
- Stream Prioritization
**개선 효과**: First load 30% 빠름, 대역폭 효율 증가
**한계**: TCP 기반이라 여전히 connection-level HOL blocking
HTTP/3 (2022) — QUIC 위에서 재탄생
특징:
- QUIC 기반 (UDP)
- Stream-level 독립성 (HOL 제거)
- 0-RTT connection resumption
- Always HTTPS (TLS 1.3 내장)
- Connection Migration
**2025 어댑션**:
- Chrome, Safari, Firefox 모두 기본 지원
- Cloudflare, Fastly, AWS CloudFront 활성화
- YouTube, Instagram, Facebook 기본
- Node.js, Go, Rust 라이브러리 성숙 (`quiche`, `quinn`, `msquic`)
실전 활성화 (Caddy, Nginx)
Caddyfile — HTTP/3 기본 활성화
example.com {
reverse_proxy localhost:3000
HTTP/3 자동
}
Nginx 1.25+
server {
listen 443 ssl http2;
listen 443 quic reuseport;
add_header Alt-Svc 'h3=":443"; ma=86400';
ssl_protocols TLSv1.3;
...
}
4부 — TLS 1.3과 HTTPS의 현재
TLS 1.3 vs 1.2 핵심 차이
| 항목 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| Handshake | 2-RTT | **1-RTT** |
| Resumption | Session ID/Ticket | **0-RTT PSK** |
| Cipher Suites | 37개 (많이 취약) | **5개** (모두 AEAD) |
| Forward Secrecy | Optional | **필수** |
| RSA Key Exchange | Yes | **제거** (ECDHE만) |
TLS 1.3 Handshake (1-RTT)
ClientHello (key share + signature_algorithms + cipher_suites)
─────►
ServerHello (key share)
EncryptedExtensions
Certificate
CertificateVerify
Finished
◄─────
Finished
Application Data (HTTP request) ─────►
**1-RTT만에 암호화된 데이터 전송 시작**. TLS 1.2는 2-RTT 필요했음.
0-RTT Resumption — 재접속은 즉시
첫 연결: 1-RTT로 key 교환 + PSK(Pre-Shared Key) 저장
재연결: ClientHello + PSK + HTTP Request (한 번에!)
**주의**: 0-RTT는 **replay attack 취약**. GET은 OK, POST/결제/상태 변경은 1-RTT 써야 함.
인증서 (Let's Encrypt 2025)
- **무료**: Let's Encrypt, ZeroSSL
- **ECDSA 권장**: RSA 2048보다 빠르고 작음
- **자동화**: Caddy, Traefik은 기본. Nginx는 certbot
- **SAN**: 와일드카드 vs 개별 (DNS-01 challenge로 와일드카드 가능)
- **Expiry 90일**: 자동 갱신 필수
Let's Encrypt with certbot
sudo certbot --nginx -d example.com -d www.example.com
자동 갱신 (cron)
0 0,12 * * * certbot renew --quiet
mTLS — 서비스 간 인증
Server 인증 뿐 아니라 Client도 인증서로 증명
사용: Service Mesh (Istio, Linkerd), Zero Trust Network
도구: cert-manager + SPIFFE/SPIRE
5부 — REST vs gRPC vs GraphQL vs tRPC
REST (2000)
GET /api/users/1
Content-Type: application/json
{"id": 1, "name": "Alice"}
**장점**: 단순, 캐싱 쉬움, 모든 언어 지원
**단점**: Over/Under-fetching, N+1 쿼리, 버저닝 어려움
GraphQL (2015)
query {
user(id: 1) {
name
posts { title }
}
}
**장점**: 정확한 데이터 쿼리, 단일 엔드포인트, 스키마 강제
**단점**: 복잡, N+1 문제 (DataLoader 필요), 캐싱 어려움
**2025 현실**: Netflix, Shopify 유지. 하지만 **"REST + 필드 선택(`?fields=name,email`)"이 더 간단**하다는 인식 증가. 신규 프로젝트는 tRPC/REST 선호.
gRPC (2015)
// user.proto
service UserService {
rpc GetUser(GetUserRequest) returns (User);
rpc StreamUsers(Empty) returns (stream User);
rpc ChatUsers(stream Message) returns (stream Message);
}
message GetUserRequest {
int64 id = 1;
}
message User {
int64 id = 1;
string name = 2;
}
**장점**:
- 바이너리 직렬화(Protobuf) → REST JSON 대비 **5-10x 빠름**
- HTTP/2 + 스트리밍 4가지 모드 (unary, server-stream, client-stream, bidi-stream)
- 강타입, 코드 생성 자동화
- 서비스 간 통신 표준 (Kubernetes 내부 다수)
**단점**:
- 브라우저 직접 호출 어려움 (gRPC-Web 필요)
- 디버깅 어려움 (바이너리)
- Human-readable 아님
**쓰는 곳**: 마이크로서비스 간, Kubernetes, Envoy, Istio, TiKV, CockroachDB
tRPC (2022) — TypeScript End-to-End
// server
const appRouter = router({
getUser: publicProcedure
.input(z.object({ id: z.number() }))
.query(async ({ input }) => {
return await db.user.findUnique({ where: { id: input.id } });
}),
});
// client
const user = await trpc.getUser.query({ id: 1 });
// ↑ 서버 스키마 그대로 타입 추론, 코드 생성 X
**2025 현실**: Next.js 풀스택 프로젝트에서 **REST/GraphQL 대체하는 기본**. Vercel, T3 Stack.
**한계**: TypeScript 전용, 서비스 간 통신(다른 언어)엔 gRPC
선택 가이드 2025
| 시나리오 | 추천 |
|---|---|
| 모노레포 TS 풀스택 | **tRPC** |
| 마이크로서비스 간 | **gRPC** |
| 외부 공개 API | **REST** (+ OpenAPI) |
| 모바일, 복잡한 데이터 그래프 | **GraphQL** |
| 브라우저 ↔ 서버 (언어 다양) | **REST + OpenAPI** |
6부 — WebSocket vs SSE vs Long Polling vs WebTransport
실시간 양방향 통신 비교
| 방식 | 방향 | 프로토콜 | 복잡도 | 추천 |
|---|---|---|---|---|
| Long Polling | client→server | HTTP | 낮음 | 레거시 |
| SSE (Server-Sent Events) | **server→client** | HTTP | 낮음 | 알림, 주가 |
| WebSocket | **양방향** | WS over TCP | 중간 | 채팅, 게임 |
| WebTransport | 양방향 | QUIC | 높음 | 2025+ 게임 |
WebSocket (2011) — 채팅의 왕
const ws = new WebSocket('wss://example.com/chat');
ws.onopen = () => ws.send(JSON.stringify({ type: 'hello' }));
ws.onmessage = (event) => console.log(JSON.parse(event.data));
ws.onclose = () => console.log('closed');
**특징**:
- HTTP로 시작 → Upgrade 헤더로 WebSocket 전환
- TCP connection 유지
- 양방향 binary/text 프레임
- ping/pong으로 keepalive
**실전 함정**:
- **재연결 로직 필수** — 네트워크 끊기면 자동 복구 안 됨
- **Backpressure** — 메시지 너무 빨리 오면 버퍼 오버플로우
- **인증** — WebSocket upgrade 시 쿠키/토큰 전달
- **로드밸런싱** — sticky session 또는 Redis pub/sub
// 재연결 with exponential backoff
class RobustWebSocket {
connect() {
this.ws = new WebSocket(this.url);
this.ws.onclose = () => {
setTimeout(() => this.connect(), Math.min(this.retry * 2, 30000));
this.retry *= 2;
};
this.ws.onopen = () => { this.retry = 1000; };
}
}
SSE (Server-Sent Events) — 단방향 간단
// client
const es = new EventSource('/api/stream');
es.onmessage = (e) => console.log(e.data);
// server (Express)
app.get('/api/stream', (req, res) => {
res.setHeader('Content-Type', 'text/event-stream');
setInterval(() => {
res.write(`data: ${JSON.stringify({ time: Date.now() })}\n\n`);
}, 1000);
});
**장점**: 자동 재연결, HTTP 기반, 방화벽 통과 쉬움
**단점**: 서버→클라이언트만, 브라우저 6 connection 제한
**2025 현실**: **LLM Streaming의 기본**. ChatGPT, Claude API는 SSE 사용.
WebTransport (2024+, 신기술)
WebSocket의 한계(TCP HOL, TLS 1.2)를 해결
기반: HTTP/3 + QUIC
특징: 양방향, stream + datagram, 0-RTT
상태: Chrome, Safari TP 지원. 2025년 점진적 확산
**쓰일 곳**: 실시간 게임, VR, 고빈도 데이터 스트리밍
7부 — CDN, Edge Computing, Anycast
CDN 기본 원리
User → DNS → 가장 가까운 PoP → Cache HIT/MISS → Origin
**용어**:
- **PoP (Point of Presence)**: CDN 서버 위치 (전 세계 200-300개)
- **Edge**: PoP에 있는 컴퓨팅 노드
- **Origin**: 원본 서버 (AWS, GCP 등)
- **Cache HIT**: PoP에 캐시됨 (빠름)
- **Cache MISS**: Origin까지 fetch
- **Anycast**: 같은 IP 주소를 전 세계 PoP가 광고 → BGP가 가장 가까운 곳으로 라우팅
CDN 2025 랜드스케이프
| 제공자 | 강점 | 2025 특징 |
|---|---|---|
| **Cloudflare** | Workers, R2, D1, Durable Objects, 광대한 PoP | Edge DB, Vector DB, AI inference |
| **Fastly** | VCL, 실시간 퍼지, Compute@Edge(Wasm) | 뉴스/미디어 강세 |
| **AWS CloudFront** | AWS 통합, Lambda@Edge | 엔터프라이즈 AWS 생태계 |
| **Vercel** | Next.js 통합, Edge Functions | 프론트엔드 배포 |
| **Akamai** | 레거시, 엔터프라이즈 | 보안 강세 |
| **Bunny** | 저가격, 단순 | 스타트업 |
Cloudflare Workers — Edge 컴퓨팅의 표준
// worker.js
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname === '/api/user') {
const user = await env.DB.prepare('SELECT * FROM users WHERE id=?')
.bind(url.searchParams.get('id'))
.first();
return Response.json(user);
}
return fetch(request); // passthrough
},
};
**특징**:
- 전 세계 300+ PoP에서 실행
- V8 isolate 기반 → 5ms cold start (Lambda는 100ms+)
- 50ms CPU 제한 (무료 10ms)
- D1(SQLite), KV, R2(S3 호환), Durable Objects, Queues
**쓰임**: A/B testing, 인증 프록시, 이미지 리사이징, AI inference, 지역별 리다이렉트
Cache-Control 헤더 이해
Cache-Control: public, max-age=3600, s-maxage=86400, stale-while-revalidate=60
- `public`: CDN/브라우저 모두 캐시
- `private`: 브라우저만 (CDN X)
- `max-age=3600`: 브라우저 1시간
- `s-maxage=86400`: CDN 1일 (우선)
- `stale-while-revalidate=60`: 만료 후 60초는 stale 서빙, 백그라운드 갱신
- `no-cache`: 매번 Origin에 확인 (If-Modified-Since)
- `no-store`: 절대 캐시 X
- `immutable`: 절대 변경 안 됨 (해시된 자산)
Cache Invalidation (유명한 2대 난제 중 하나)
**전략 비교**:
1. **Path purge**: `/api/user/1` 특정 URL 제거
2. **Surrogate key / Cache Tag**: `Cache-Tag: user:1` → 태그 기준 일괄 제거 (Fastly, Cloudflare Enterprise)
3. **Versioning**: `/api/v2/user/1` — 새 버전 배포
4. **Content hash**: `/static/app.a3f9.js` — 파일 내용 변경되면 해시 변경
**2025 현실**: 대규모 시스템은 **Surrogate Key + stale-while-revalidate**.
Origin Shield — CDN 앞의 CDN
Edge → Origin Shield (단일 PoP) → Origin
**효과**: 300개 PoP가 각자 Origin 치는 대신 1개 Shield가 Origin 침 → Origin 부하 **90% 감소**.
8부 — DNS, Anycast, BGP
DNS 2025 — 빠르고 암호화된
**DoH (DNS over HTTPS)**: 1.1.1.1, 8.8.8.8 (Cloudflare, Google)
**DoT (DNS over TLS)**: 포트 853
**DNSSEC**: 서명으로 변조 방지 (2024년부터 ccTLD 대부분 지원)
DNS 레코드 타입 핵심
| 타입 | 용도 | 예시 |
|---|---|---|
| A | IPv4 | `example.com → 1.2.3.4` |
| AAAA | IPv6 | `example.com → 2001:db8::1` |
| CNAME | alias | `www → example.com` |
| MX | 메일 | `mail.example.com` |
| TXT | SPF, DKIM, verification | |
| CAA | 인증서 발급 제한 | `0 issue "letsencrypt.org"` |
| ALIAS/ANAME | root domain CNAME hack | |
Anycast — 하나의 IP, 수백 개 위치
1.1.1.1 (Cloudflare DNS)
전 세계 300개 PoP가 같은 IP를 BGP로 광고
사용자 패킷은 가장 가까운 PoP로 자동 라우팅
**장점**: DDoS 완화(공격 분산), 지연 감소
**단점**: TCP connection은 state 유지되어야 해서 복잡 (Cloudflare Unimog 같은 LB 필요)
BGP — 인터넷의 라우팅 프로토콜
**한 줄 요약**: "나는 1.2.3.0/24를 가지고 있어" — ISP들이 서로 광고
**사고 사례**: 2021 Facebook outage — BGP 광고 실수로 자사 DNS 접근 불가 → 6시간 다운
**보안**: RPKI(Route Origin Authorization)로 BGP hijacking 방지
9부 — 네트워크 디버깅 툴킷
레이어별 도구
L1-L2: ethtool, mii-tool (잘 안 씀)
L3 IP: ping, traceroute, mtr
L4 TCP/UDP: netstat, ss, tcpdump, Wireshark
L7 HTTP: curl, httpie, Postman, Wireshark (HTTPS는 TLS 키 필요)
DNS: dig, nslookup, dog (Rust)
필수 명령어
1. 연결 확인
ping google.com
curl -I https://example.com # 헤더만
2. DNS
dig example.com A +short
dig @1.1.1.1 example.com # 특정 resolver 사용
3. 경로 확인
traceroute google.com
mtr google.com # 실시간 경로 + 패킷 손실
4. 소켓 상태
ss -tunap # TCP/UDP, 리스닝, PID
ss -s # 요약 (ESTABLISHED 개수 등)
5. 패킷 캡처
sudo tcpdump -i any -w capture.pcap port 443
wireshark capture.pcap # GUI로 분석
6. HTTP/3 테스트
curl --http3 https://cloudflare.com -v
7. TLS 분석
openssl s_client -connect example.com:443 -tls1_3
또는 modern 도구
testssl.sh example.com
성능 측정
대역폭
iperf3 -s # server
iperf3 -c server.com -t 30 # client
응답 시간 (curl format)
curl -w "@curl-format.txt" -o /dev/null -s https://example.com
curl-format.txt:
time_namelookup: %{time_namelookup}s\n
time_connect: %{time_connect}s\n
time_appconnect: %{time_appconnect}s\n
time_starttransfer: %{time_starttransfer}s\n
time_total: %{time_total}s\n
10부 — 네트워크 성능 튜닝
TCP 튜닝 (Linux)
/etc/sysctl.conf
net.core.rmem_max = 134217728 # 수신 버퍼 128MB
net.core.wmem_max = 134217728 # 송신 버퍼 128MB
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.ipv4.tcp_congestion_control = bbr # Google BBR (cubic 기본보다 좋음)
net.ipv4.tcp_fastopen = 3 # TFO (0-RTT for TCP)
net.core.somaxconn = 65535 # accept queue
BBR — Google이 만든 혼잡 제어
기존 CUBIC: 패킷 손실 → 혼잡 가정 → 윈도우 줄임
BBR: 대역폭(BtlBw) + 지연(RTprop) 추정 → 실제 용량 대비 전송
효과: 고지연 네트워크(국제선)에서 2-10x 처리량
사용: YouTube, Google Cloud 기본
Keep-Alive는 무조건 켜라
HTTP: Connection: keep-alive (HTTP/1.1 기본)
TCP: SO_KEEPALIVE
이유: 새 연결 Handshake 비용 (TCP 1-RTT + TLS 1-RTT)
주의: Load balancer timeout보다 client keepalive 짧게
CDN 활용 체크리스트
- [ ] 정적 자산(JS/CSS/이미지) CDN 서빙
- [ ] `Cache-Control: public, max-age=31536000, immutable` (해시된 파일)
- [ ] HTML은 `stale-while-revalidate`
- [ ] API 응답도 캐시 가능하면 캐시 (GET, 공개)
- [ ] Brotli 압축 활성화 (gzip보다 20% 작음)
- [ ] HTTP/3 활성화
- [ ] 이미지: WebP/AVIF, `<picture>` fallback
- [ ] Origin Shield (대규모)
- [ ] Cache Tag 기반 purge
11부 — 실전 장애 시나리오 5가지
케이스 1: "API가 간헐적으로 느림"
**증상**: 평소 50ms, 가끔 5000ms 스파이크
**디버깅**:
1. DNS TTL 확인 — 짧으면 DNS lookup 매번 발생
2. Keep-alive 확인 — 새 connection마다 TLS handshake
3. Connection pool 확인 — pool exhausted → 새 connection 대기
**해결**: DNS TTL 늘리고, HTTP client에 connection pool 크게
케이스 2: "한국에서만 느림"
**증상**: 미국 50ms, 한국 500ms
**원인**: Origin이 us-east, CDN 없음
**해결**: CDN 추가, Seoul PoP 사용, Origin Shield
케이스 3: "WebSocket이 끊김"
**증상**: 30초마다 끊어짐
**원인**: Load balancer idle timeout (AWS ALB 60초, Cloudflare 100초)
**해결**: ping/pong 30초 간격, LB timeout 늘림
케이스 4: "HTTP/3 켰더니 느려짐"
**증상**: HTTP/2 대비 느림
**원인**: 기업 방화벽/VPN이 UDP:443 차단 → fallback to HTTP/2
**해결**: `Alt-Svc` 헤더 설정, QUIC bit 확인, fallback 정상 동작 확인
케이스 5: "TLS handshake가 800ms"
**증상**: 정상 150ms, 가끔 800ms
**원인**: OCSP stapling 미사용 → 브라우저가 CA에 revocation 확인
**해결**: Nginx `ssl_stapling on;`, Must-Staple 인증서
12부 — Zero Trust와 Service Mesh
Zero Trust Network
원칙: "네트워크 내부도 신뢰하지 않는다"
구현:
- mTLS (서비스 간 상호 인증)
- 짧은 인증서 TTL (1시간)
- Identity-aware proxy (Google IAP, Cloudflare Access)
- Microsegmentation (NetworkPolicy)
Service Mesh 비교
| 항목 | Istio | Linkerd | Cilium |
|---|---|---|---|
| 데이터 plane | Envoy | Rust proxy | eBPF |
| 오버헤드 | 높음 | 중간 | 낮음 |
| 복잡도 | 매우 높음 | 낮음 | 중간 |
| mTLS | ✅ | ✅ | ✅ |
| 2025 추세 | 감소 | 유지 | **증가** |
**2025 현실**: **Cilium이 CNI + Service Mesh 통합**으로 세대교체 중. eBPF로 사이드카 없이 mTLS.
13부 — 6개월 로드맵
**1개월차**: curl, dig, ss, tcpdump 익숙해지기. 내 서비스 TCP/TLS handshake 측정
**2개월차**: HTTP/1.1 → 2 → 3 차이 실습. Caddy로 HTTP/3 활성화
**3개월차**: TLS 1.3, Let's Encrypt, mTLS 실습. ALPN, SNI 이해
**4개월차**: REST, gRPC, tRPC 작은 서비스 각각 구현. 성능 비교
**5개월차**: CDN 도입 (Cloudflare). Cache-Control, Surrogate Key, Origin Shield
**6개월차**: 장애 시뮬레이션 (tc로 지연/손실 주입). BBR, TCP 튜닝. Zero Trust 개념
14부 — 체크리스트 12개
- [ ] HTTP/3 활성화 (Alt-Svc 헤더 확인)
- [ ] TLS 1.3 only, TLS 1.0/1.1 disable
- [ ] HSTS 헤더 (`max-age=31536000; includeSubDomains; preload`)
- [ ] Let's Encrypt 자동 갱신 (`certbot renew`)
- [ ] OCSP stapling 활성화
- [ ] BBR congestion control
- [ ] TCP keep-alive + HTTP keep-alive
- [ ] CDN 도입 (정적 자산 + API 캐시)
- [ ] Brotli 압축
- [ ] 이미지 WebP/AVIF
- [ ] HTTP 캐시 헤더 정책 문서화
- [ ] WebSocket 재연결 + backpressure
15부 — 안티패턴 10가지
1. **HTTP만 서빙** (HTTPS 미적용) → 브라우저가 "안전하지 않음" 경고
2. **TLS 1.0/1.1 유지** → PCI-DSS 위반, 취약점
3. **CDN 없이 글로벌 서비스** → 한국 사용자 800ms 지연
4. **Keep-alive 비활성화** → 매 요청 handshake
5. **Cache-Control 미설정** → CDN 캐시 활용 못함
6. **GraphQL 캐싱 안 함** → N+1 폭발
7. **WebSocket 재연결 로직 없음** → LB timeout 시 영구 끊김
8. **DNS TTL 너무 김** (86400) → 장애 시 페일오버 느림
9. **Cache Invalidation을 수동으로** → 스케일 불가, Surrogate Key 필수
10. **TCP BBR 미적용** → 국제선 느림
마무리 — "패킷이 어디로 가는지 알면 디버깅이 달라진다"
네트워크는 보이지 않는다. 그래서 **느리면 범인을 모른다**.
- DNS 느림? `dig`로 확인
- TLS 느림? `openssl s_client`로 확인
- 중간 네트워크 느림? `mtr`로 확인
- CDN 캐시 안 됨? `curl -I`로 헤더 확인
- HTTP/3 안 됨? `curl --http3 -v`로 확인
2025년 네트워크의 핵심 키워드는 **QUIC, Edge, Zero Trust**.
이 셋이 HTTP를 재정의하고, CDN을 Edge로 확장하고, 보안을 기본값으로 만든다.
다음 글은 Season 2 Ep 15 — **클라우드 네이티브 완전 가이드**.
Kubernetes, Service Mesh, Serverless, FaaS, Container Runtime, eBPF까지.
네트워크가 배관이면, 클라우드 네이티브는 **그 위의 도시**다.
다음 글 예고 — "클라우드 네이티브 완전 가이드: Kubernetes·Serverless·eBPF·Container"
Season 2 Ep 15는 2025년 인프라의 표준, **클라우드 네이티브**. 다음 글은:
- Kubernetes 핵심 개념 (Pod, Service, Ingress, CRD)
- Serverless vs Container vs VM 선택
- eBPF 혁명 (Cilium, Falco, Pixie)
- Container Runtime (containerd, Kata, Firecracker)
- GitOps (ArgoCD, Flux)
- Cost optimization (Karpenter, Spot)
배관 위에 도시를 짓는다. 다음 글에서.
현재 단락 (1/444)
2025년 4월, 당신의 REST API가 한국에서 200ms, 미국에서 800ms 걸린다.