TL;DR
- **HTTP/3 = HTTP over QUIC**: 의미는 같고 전송 계층이 다름
- **QUIC = UDP 기반 신뢰성 프로토콜**: TCP의 모든 단점 해결
- **3가지 혁신**: 0-RTT 핸드셰이크, Stream 독립성 (HOL 해결), Connection Migration
- **이미 사실상 표준**: Google, Facebook, Cloudflare, Fastly 모두 사용
- **HTTP/2 대비**: 페이지 로딩 10-30% 개선, 모바일에서 더 큼
1. HTTP의 진화
1.1 HTTP/1.0 (1996)
GET /index.html HTTP/1.0
HTTP/1.0 200 OK
Content-Type: text/html
Content-Length: 1234
**특성**:
- 단순 텍스트
- **요청당 1 연결** (TCP setup + teardown)
- 헤더 매번 전송
**문제**: 연결 비용 폭증.
1.2 HTTP/1.1 (1997)
**개선**:
- **Keep-alive** (지속 연결)
- **Pipelining** (요청 큐잉)
- 청크 전송
- **Host 헤더** (가상 호스팅)
**여전한 문제**:
- **Head-of-Line Blocking**: 첫 응답이 늦으면 뒤따르는 모든 응답 대기
- 한 연결당 1 요청 (실제로는)
- 헤더 압축 X
- 평문
1.3 HTTP/2 (2015)
**대혁신**:
- **이진 프로토콜** (텍스트 X)
- **멀티플렉싱**: 단일 연결에 여러 stream
- **HPACK 헤더 압축**
- **서버 푸시** (사실상 deprecated)
- **HTTPS 사실상 필수**
**개선 효과**:
- 페이지 로딩 30%+ 빠름
- 헤더 80%+ 감소
**여전한 문제**:
- **TCP HOL Blocking**: 한 패킷 손실이 모든 stream 차단
- TCP + TLS 핸드셰이크 = 3 RTT
- TCP의 근본적 한계
1.4 HTTP/3 (2022)
**전송 계층 교체**:
- TCP → **QUIC** (UDP 기반)
- TLS 1.3 통합
- HOL Blocking 해결
이건 단순 업데이트가 아니라 **근본적 재설계**입니다.
2. TCP의 문제들
2.1 핸드셰이크 비용
[Client] [Server]
│ │
├──── TCP SYN ──────────────────→│ ← 1 RTT
│←─── SYN+ACK ───────────────────┤
├──── ACK ──────────────────────→│
│ │
├──── TLS ClientHello ──────────→│ ← 1 RTT
│←─── ServerHello, Certificate ──┤
├──── Finished ─────────────────→│ ← 1 RTT
│←─── Finished ──────────────────┤
│ │
├──── HTTP Request ─────────────→│ ← 1 RTT
│←─── HTTP Response ─────────────┤
**총 4 RTT**. 100ms 핑이면 400ms 첫 응답.
2.2 Head-of-Line Blocking
TCP 연결 (HTTP/2):
Stream 1: ●●●●●● (이미지)
Stream 2: ●●●●●● (CSS)
Stream 3: ●●●●●● (JS)
패킷 손실 발생:
●●●❌●● ← 손실
↑
TCP가 재전송 + 재정렬 대기
↓
Stream 1, 2, 3 모두 멈춤! ← 한 stream의 손실이 전체 차단
**근본 원인**: TCP는 byte stream만 알고, HTTP/2 stream은 모름.
2.3 Connection Migration 불가능
TCP 연결 = `(src_ip, src_port, dst_ip, dst_port)` 4-tuple.
**모바일 시나리오**:
1. 카페 WiFi에서 Netflix 시청
2. 카페 나옴 → 4G로 전환
3. **IP 변경** → 연결 끊김
4. 새 연결 + 인증 + 비디오 buffering
**사용자 경험**: 끊김.
2.4 TCP의 근본적 한계
이 문제들은 **TCP를 패치할 수 없습니다**:
- 모든 OS, 모든 라우터, 모든 미들박스가 TCP를 알고 있음
- TCP 변경 = 인터넷 전체 변경
- 새 프로토콜이 필요
3. QUIC의 등장
3.1 Google의 시도
**2012**: Google이 내부에서 QUIC 시작.
**2013**: Chrome에 실험적 배포.
**2018**: IETF 표준화 시작.
**2021**: RFC 9000 (QUIC 표준).
**2022**: RFC 9114 (HTTP/3 표준).
3.2 왜 UDP?
UDP는 단순함:
- 패킷 송수신만
- 순서 보장 X
- 신뢰성 X
- 흐름 제어 X
→ **QUIC가 사용자 공간에서 모든 것을 구현**.
3.3 QUIC의 핵심 아이디어
┌─────────────────────┐
│ HTTP/3 │
├─────────────────────┤
│ QUIC │ ← 사용자 공간
│ (Streams, TLS, │
│ Reliability, │
│ Flow Control) │
├─────────────────────┤
│ UDP │ ← 커널
├─────────────────────┤
│ IP │
└─────────────────────┘
**효과**:
- 커널 변경 불필요
- 빠른 진화 (사용자 공간에서)
- 미들박스가 간섭 못 함
4. QUIC의 혁신
4.1 0-RTT 핸드셰이크
**처음 연결 (1-RTT)**:
[Client] [Server]
│ │
├──── Initial (TLS ClientHello) →│ ← 1 RTT
│←─── Initial (ServerHello, ─┤
│ Certificate, Finished) │
├──── HTTP Request ─────────────→│
TCP+TLS의 4 RTT → **1 RTT**.
**재방문 (0-RTT)**:
[Client] [Server]
│ │
├──── Initial + HTTP Request ───→│ ← 0 RTT!
│←─── Response ──────────────────┤
이전 세션의 키를 캐시 → **첫 패킷에 데이터 포함**.
4.2 0-RTT의 보안
**Replay attack 위험**:
- 0-RTT 데이터는 재생될 수 있음
- GET은 OK (idempotent)
- POST는 위험
**해결**:
- 0-RTT는 idempotent 요청만
- 서버가 0-RTT 거부 가능
- TLS 1.3의 `early_data` 메커니즘
4.3 Stream 멀티플렉싱
QUIC 연결:
Stream 1: ●●●●●●
Stream 2: ●●●●●●
Stream 3: ●●●●●●
패킷 손실:
Stream 2: ●●●❌●● ← Stream 2만 영향
Stream 1: ●●●●●● ← 영향 없음 ✅
Stream 3: ●●●●●● ← 영향 없음 ✅
**핵심**: 각 stream이 **독립적인 순서 보장**. HTTP/2의 HOL blocking 해결.
4.4 Connection Migration
QUIC 연결 = **Connection ID** (4-tuple X).
**모바일 시나리오**:
1. WiFi에서 영상 시청 (Connection ID: ABC123)
2. 4G로 전환 (IP 변경)
3. **같은 Connection ID로 계속**
4. 서버가 인식 → 끊김 없이 계속
**NAT rebinding에도 강함**:
- 모바일 NAT가 IP/포트 바꿔도
- Connection ID로 식별
- 끊김 없음
4.5 Forward Error Correction (선택)
일부 QUIC 구현은 FEC 지원:
- 손실 예측 패킷 추가 전송
- 손실 시 복구 가능 (재전송 X)
- 모바일에서 효과적
5. QUIC vs TCP 상세 비교
5.1 핸드셰이크
| | TCP+TLS 1.3 | QUIC |
|---|---|---|
| **첫 연결** | 2-3 RTT | **1 RTT** |
| **재연결** | 1-2 RTT | **0 RTT** |
5.2 HOL Blocking
| | TCP | QUIC |
|---|---|---|
| **패킷 손실 시** | 모든 stream 차단 | 해당 stream만 |
5.3 Connection Migration
| | TCP | QUIC |
|---|---|---|
| **IP 변경** | 연결 끊김 | **유지** |
| **NAT rebinding** | 끊김 | 유지 |
5.4 암호화
| | TCP+TLS | QUIC |
|---|---|---|
| **암호화** | TLS over TCP | **통합** (의무) |
| **메타데이터** | 일부 노출 | 거의 모두 암호화 |
5.5 진화 속도
| | TCP | QUIC |
|---|---|---|
| **위치** | 커널 | 사용자 공간 |
| **업데이트** | OS 업데이트 필요 | 앱 업데이트만 |
6. HTTP/3의 변화
6.1 메시지 형식
**HTTP/2** (이진):
프레임 헤더 + 페이로드
**HTTP/3** (QUIC 위):
- 프레임 형식 유사
- 하지만 stream별 독립
6.2 헤더 압축
**HTTP/2**: HPACK
**HTTP/3**: **QPACK**
QPACK이 HPACK과 다른 이유:
- HPACK은 stream 순서에 의존 → HOL blocking 발생
- QPACK은 순서 무관 (QUIC stream 독립성에 맞춤)
6.3 Server Push
**HTTP/2 Server Push**: 사실상 deprecated (Chrome 106+ 비활성).
**HTTP/3**: Server Push 옵션, 거의 사용 안 함.
**대안**: **103 Early Hints**.
6.4 새로운 응답 코드
**103 Early Hints**:
HTTP/2 103 Early Hints
Link: </styles.css>; rel=preload; as=style
Link: </script.js>; rel=preload; as=script
HTTP/2 200 OK
Content-Type: text/html
...
서버가 본 응답 전에 "이런 자원을 미리 받으세요"라고 힌트. Server Push의 더 좋은 대안.
7. 성능 벤치마크
7.1 페이지 로딩 시간
**Cloudflare 데이터** (HTTP/2 → HTTP/3):
- **데스크톱**: 5-10% 개선
- **모바일 (4G)**: 15-25% 개선
- **모바일 (3G)**: 30%+ 개선
**Google 데이터** (YouTube):
- 비디오 시작 시간 9% 개선
- Rebuffering 16% 감소
**Facebook 데이터**:
- 페이지 로드 시간 6% 개선
- 비디오 시작 시간 20% 개선
7.2 패킷 손실 환경
**1% 패킷 손실** (좋은 모바일 환경):
- HTTP/2: 큰 latency 증가
- HTTP/3: 약간만
**5% 패킷 손실** (나쁜 환경):
- HTTP/2: 거의 사용 불가
- HTTP/3: 여전히 작동
QUIC가 진가를 발휘하는 환경: **모바일, 멀리 떨어진 사용자**.
7.3 CPU 사용량
**문제**: QUIC는 사용자 공간에서 작동 → CPU 부담.
HTTP/2 (TCP): 커널이 모든 것 처리
HTTP/3 (QUIC): 사용자 공간에서 처리
**서버**:
- 같은 트래픽에 1.5-2배 CPU
- 큰 오버헤드
**해결책**:
- **GSO/GRO** (Generic Segmentation/Receive Offload)
- 하드웨어 가속 (eBPF, XDP)
- 더 효율적인 QUIC 구현
8. 배포
8.1 어떻게 시작?
**Alt-Svc 헤더**:
HTTP/2 200 OK
Alt-Svc: h3=":443"; ma=86400
브라우저가 다음 요청부터 HTTP/3로 시도. 실패 시 HTTP/2로 fallback.
**효과**: **점진적 마이그레이션**, 위험 없음.
8.2 서버 옵션
**Nginx**:
server {
listen 443 quic reuseport;
listen 443 ssl;
http2 on;
http3 on;
add_header Alt-Svc 'h3=":443"; ma=86400';
}
**Caddy**: 자동 (HTTPS 자동 + HTTP/3 자동).
example.com {
root * /var/www
file_server
}
이게 전부. HTTP/3 자동 활성화.
8.3 CDN
**HTTP/3 지원**:
- **Cloudflare**: ✅ 무료 티어부터
- **Fastly**: ✅
- **AWS CloudFront**: ✅
- **Azure CDN**: ✅
- **Google Cloud CDN**: ✅
- **Akamai**: ✅
→ CDN 사용 시 **이미 HTTP/3 사용 중**일 가능성 높음.
8.4 클라이언트 지원
**브라우저** (2024년 말):
- **Chrome**: 88+ (2021년부터 기본 활성)
- **Firefox**: 88+
- **Safari**: 14+ (iOS/macOS)
- **Edge**: Chromium 기반
**라이브러리**:
- `quiche` (Cloudflare, Rust + C)
- `quinn` (Rust)
- `lsquic` (LiteSpeed)
- `mvfst` (Facebook)
- `MsQuic` (Microsoft)
8.5 방화벽 문제
**기업 방화벽**이 UDP를 차단하는 경우:
- HTTP/3 작동 안 함
- HTTP/2로 fallback
- Alt-Svc 덕분에 자동
**문제**: Latency 증가 (실패 → fallback).
9. 디버깅과 모니터링
9.1 Wireshark
QUIC 디코딩 지원 (Wireshark 3.4+):
- TLS 1.3 키 추출 필요 (`SSLKEYLOGFILE`)
- Chrome으로 캡처 후 분석
9.2 qlog
QUIC 표준 로깅 형식:
- JSON 기반
- 타임라인 시각화
**도구**:
- **qvis**: qlog 시각화
- 패킷, 핸드셰이크, 스트림 추적
9.3 Chrome DevTools
chrome://net-export/ → 네트워크 로그
chrome://flags/#enable-quic
9.4 OpenSSL은 안 됨
OpenSSL은 QUIC 지원이 늦음 (2024년 OpenSSL 3.2+ 부분 지원).
**대안**:
- BoringSSL (Google)
- quictls (OpenSSL fork)
10. 미래
10.1 HTTP/3의 채택
**2024년 말**:
- Cloudflare 트래픽의 ~30% HTTP/3
- Chrome 사용자의 ~25% HTTP/3
- 점진적 증가
10.2 MASQUE
QUIC 위의 프록시 프로토콜:
- VPN 대안
- HTTP CONNECT의 후속작
- IETF 표준화 진행
**Apple Private Relay**: MASQUE 사용.
10.3 WebTransport
WebSocket의 후속작:
- QUIC 기반
- 양방향, 다중 stream
- 신뢰성/비신뢰성 둘 다
const transport = new WebTransport('https://example.com:4433/api')
await transport.ready
// 신뢰성 stream
const stream = await transport.createBidirectionalStream()
const writer = stream.writable.getWriter()
writer.write(new TextEncoder().encode("Hello"))
10.4 QUIC for Everything
QUIC은 HTTP에만 국한되지 않습니다:
- **DNS over QUIC** (RFC 9250)
- **WebRTC over QUIC**
- **SSH over QUIC** (실험적)
UDP 위의 신뢰성 있는 새 프로토콜의 표준이 되어가는 중.
10.5 HTTP/4?
이미 논의 중:
- 2025년에 막 시작
- HTTP/3가 충분히 좋음
- 큰 변화 없을 것으로 예상
퀴즈
**답**: (1) **0-RTT 핸드셰이크** — 재방문 시 첫 패킷에 데이터 포함, latency 0, (2) **HOL Blocking 해결** — TCP는 한 stream의 패킷 손실이 모든 stream 차단, QUIC는 stream별 독립적 순서 보장, (3) **Connection Migration** — IP 변경에도 연결 유지 (모바일에 핵심), (4) **TLS 1.3 통합** — 핸드셰이크 RTT 절약. 모바일과 패킷 손실 환경에서 효과 극대화. 데스크톱 좋은 네트워크에서는 5-10%, 모바일에서는 25%+ 개선.
**답**: TCP를 변경할 수 없기 때문입니다. **TCP는 모든 OS, 라우터, 미들박스에 구현**되어 있어 변경하면 인터넷 전체 변경이 필요. UDP는 단순한 패킷 송수신만 제공 → QUIC가 **사용자 공간에서 모든 것 (신뢰성, 흐름 제어, 암호화)을 구현**. 장점: (1) 커널 업데이트 불필요, (2) 빠른 진화 (앱 업데이트만), (3) 미들박스 간섭 회피. 단점: CPU 사용량 증가 (커널 → 사용자 공간).
**답**: TCP 연결은 **(src_ip, src_port, dst_ip, dst_port) 4-tuple**로 식별됩니다. IP 하나만 바뀌어도 연결 끊김. 모바일 시나리오: 카페 WiFi → 4G 전환 시 IP 변경 → 연결 끊김 → 새 연결 + 인증 + buffering = 사용자 경험 망가짐. **QUIC은 Connection ID로 식별** → IP 바뀌어도 같은 연결 유지. NAT rebinding에도 강함. **YouTube, Netflix 같은 비디오 스트리밍에 큰 효과**.
**답**: **Replay attack** — 공격자가 캡처한 0-RTT 패킷을 재생할 수 있습니다. 일반 핸드셰이크는 nonce로 방지하지만, 0-RTT는 이전 세션의 키를 사용하므로 unique하지 않음. **해결**: (1) **Idempotent 요청만 0-RTT** — GET은 OK, POST는 위험, (2) 서버가 0-RTT 거부 가능, (3) **anti-replay 메커니즘** — 시간 윈도우 검증, nonce 기반. 대부분의 라이브러리는 자동 처리하지만, 애플리케이션 레벨에서 의식 필요.
**답**: **Alt-Svc 헤더** 덕분입니다. 서버가 `Alt-Svc: h3=":443"; ma=86400`을 보내면 브라우저는 다음 요청부터 HTTP/3 시도. **실패 시 자동 fallback** to HTTP/2. 결과: 점진적 마이그레이션, 단일 사용자도 영향 없음. 또한 **Cloudflare, Fastly, CloudFront 등 CDN이 자동으로** HTTP/3 활성화. 기업 방화벽이 UDP 차단해도 HTTP/2로 fallback. **새 기술이지만 채택 위험이 거의 0**.
참고 자료
- [RFC 9000 — QUIC](https://datatracker.ietf.org/doc/html/rfc9000)
- [RFC 9114 — HTTP/3](https://datatracker.ietf.org/doc/html/rfc9114)
- [HTTP/3 Explained](https://http3-explained.haxx.se/) — Daniel Stenberg
- [Cloudflare HTTP/3](https://blog.cloudflare.com/http3-the-past-present-and-future/)
- [Google QUIC](https://www.chromium.org/quic/)
- [quiche](https://github.com/cloudflare/quiche) — Cloudflare 구현
- [quinn](https://github.com/quinn-rs/quinn) — Rust 구현
- [qlog](https://qlog.edm.uhasselt.be/) — 시각화
- [QUIC Working Group](https://datatracker.ietf.org/wg/quic/)
- [HTTP/3 Adoption](https://w3techs.com/technologies/details/ce-http3) — 통계
- [WebTransport](https://web.dev/webtransport/) — Google
현재 단락 (1/319)
- **HTTP/3 = HTTP over QUIC**: 의미는 같고 전송 계층이 다름