본문 바로가기
카테고리 없음

HTTP/1.1 vs HTTP/2 vs HTTP/3 — 네트워크 기초

by SuldenLion 2026. 7. 27.
반응형
HTTP/1.1 vs HTTP/2 vs HTTP/3 — 네트워크 기초

HTTP 버전 한눈에 보기

HTTP/1.1
1997년 RFC 2068
텍스트 기반 프로토콜. Keep-Alive 연결. 요청 파이프라이닝 (제한적). 헤더 압축 없음.
HTTP/2
2015년 RFC 7540
바이너리 프레임. 스트림 멀티플렉싱. HPACK 헤더 압축. 서버 푸시. TLS 사실상 필수.
HTTP/3
2022년 RFC 9114
QUIC(UDP) 기반. TCP HOL Blocking 완전 제거. 0-RTT 연결. 연결 마이그레이션 지원.

HTTP/1.1 — 오래된 거인

HTTP/1.1은 1997년 등장해 10년 넘게 웹의 유일한 표준으로 사용됐다. 현재도 전 세계 수많은 서버에서 동작하고 있다. 텍스트 기반의 단순한 설계가 이해하기 쉽고 디버깅이 편하다는 장점이 있지만, 성능 한계가 명확하다.

Keep-Alive 연결

HTTP/1.0은 요청마다 TCP 연결을 새로 맺었다. HTTP/1.1은 Keep-Alive로 하나의 TCP 연결을 재사용한다. 하지만 한 연결에서 요청은 여전히 순차적이다 — 앞 요청의 응답을 받아야 다음 요청을 보낼 수 있다.

파이프라이닝의 한계

HTTP/1.1은 파이프라이닝(Pipelining)으로 응답을 기다리지 않고 요청을 연속 전송할 수 있도록 했다. 하지만 서버는 요청 순서대로 응답해야 해서 첫 번째 응답이 느리면 이후 응답도 모두 기다려야 한다 — 이를 HOL(Head-of-Line) Blocking이라 한다. 브라우저들이 파이프라이닝을 거의 사용하지 않는 이유다.

⚠️ HOL Blocking 회피 꼼수
브라우저는 HOL Blocking을 피하기 위해 도메인당 6~8개의 병렬 TCP 연결을 맺는다. 또한 리소스를 여러 도메인에 분산하는 도메인 샤딩(Domain Sharding)을 사용하기도 한다. 이는 서버 입장에서 매우 비효율적이다.

HTTP/2 — 바이너리 멀티플렉싱

HTTP/2는 2015년 Google의 SPDY 프로토콜을 기반으로 표준화됐다. HTTP/1.1과 의미론(Semantics)은 동일하다 — 메서드(GET, POST...), 헤더, 상태 코드가 그대로다. 바뀐 것은 데이터를 전송하는 방식이다.

핵심 기능 1: 바이너리 프레이밍

HTTP/1.1이 텍스트 기반이라면, HTTP/2는 모든 메시지를 바이너리 프레임으로 분해한다. 프레임은 더 효율적으로 파싱되고, 멀티플렉싱의 기반이 된다.

핵심 기능 2: 스트림 멀티플렉싱

HTTP/2는 하나의 TCP 연결 위에 여러 스트림(Stream)을 동시에 열 수 있다. 각 스트림은 독립적인 요청-응답 쌍이며, 순서와 관계없이 인터리빙되어 전송된다. HOL Blocking이 해결된다.

HTTP/1.1
TCP 연결 #1
GET /index.html
⬇ 대기...
GET /style.css
⬇ 대기...
GET /app.js
+ 5개 추가 연결 병렬
HTTP/2
TCP 연결 1개
Stream 1
index
Stream 3
css
Stream 5
js
동시 멀티플렉싱 ✓
HTTP/3
QUIC (UDP) 1개
Stream 1
index
Stream 3
css
Stream 5
js
TCP HOL도 제거 ✓

핵심 기능 3: HPACK 헤더 압축

HTTP/1.1에서는 매 요청마다 동일한 헤더(Host, Cookie, Accept, User-Agent...)가 반복 전송된다. HTTP/2의 HPACK은 헤더를 압축하고 이전에 전송한 헤더를 정적/동적 테이블에 저장해 인덱스 번호만 보낸다. 반복 헤더 전송량을 크게 줄인다.

핵심 기능 4: 서버 푸시

서버가 클라이언트의 요청 없이 리소스를 미리 보내는 기능이다. HTML 응답과 함께 CSS, JS를 미리 푸시하면 클라이언트가 HTML을 파싱한 후 다시 요청하는 지연을 없앤다. 다만 실제 활용이 예측하기 어렵고 캐시 중복 문제가 있어 HTTP/2에서도 실무 사용이 줄었고, HTTP/3에서는 제거되었다.

⚠️ HTTP/2의 남은 문제: TCP HOL Blocking
HTTP/2는 애플리케이션 레벨의 HOL Blocking을 해결했지만, 하나의 TCP 연결을 공유하기 때문에 TCP 레벨의 HOL Blocking은 여전히 존재한다. TCP 패킷 하나가 유실되면, 해당 연결의 모든 HTTP/2 스트림이 재전송을 기다려야 한다.

HTTP/3 — QUIC으로의 전환

HTTP/3는 2022년 RFC 9114로 표준화됐다. 가장 큰 변화는 전송 계층을 TCP에서 QUIC(UDP 기반)으로 교체한 것이다.

TCP HOL Blocking 완전 해결

QUIC은 각 스트림을 완전히 독립적으로 관리한다. 스트림 3의 패킷이 유실되어도 스트림 1, 5는 영향받지 않는다. TCP에서는 불가능했던 진정한 스트림 독립성이 실현된다.

0-RTT 연결 수립

이전에 접속했던 서버에 재연결 시, QUIC은 저장된 세션 정보로 0-RTT — 즉, 핸드셰이크 없이 첫 번째 패킷에 데이터를 실어 보낼 수 있다. 최초 연결도 TLS를 내장해 1-RTT로 완료된다.

연결 마이그레이션

TCP 연결은 4-튜플(src IP, src Port, dst IP, dst Port)로 식별된다. 스마트폰이 Wi-Fi에서 LTE로 전환되면 IP가 바뀌어 TCP 연결이 끊긴다. QUIC은 Connection ID로 연결을 식별하므로 IP가 바뀌어도 연결이 유지된다.

버전별 비교표

특성HTTP/1.1HTTP/2HTTP/3
전송 계층TCPTCPQUIC (UDP)
메시지 형식텍스트바이너리 프레임바이너리 프레임
멀티플렉싱❌ (연결 여러 개로 우회)✅ 스트림✅ 스트림
앱 레벨 HOL❌ 존재✅ 해결✅ 해결
TCP 레벨 HOL❌ 존재❌ 존재✅ 해결 (QUIC)
헤더 압축❌ 없음✅ HPACK✅ QPACK
서버 푸시✅ (실무 활용 제한)❌ (제거됨)
연결 수립1 RTT + TLS1 RTT + TLS1 RTT (0-RTT 재연결)
연결 마이그레이션✅ Connection ID
암호화HTTPS 선택사실상 필수필수 (내장)

실습: 버전 확인하기

# curl로 HTTP 버전 확인
$ curl -sI --http1.1 https://www.google.com | head -1
HTTP/1.1 200 OK

$ curl -sI --http2 https://www.google.com | head -1
HTTP/2 200

$ curl -sI --http3 https://www.google.com | head -1  # curl 7.88+ 필요
HTTP/3 200

# 브라우저 개발자 도구 → Network 탭 → Protocol 열에서 h1/h2/h3 확인 가능
# Nginx HTTP/2 설정
server {
    listen 443 ssl http2;
    ssl_certificate /etc/ssl/cert.pem;
    ssl_certificate_key /etc/ssl/key.pem;
    ...
}

# Nginx HTTP/3 (QUIC) 설정 (nginx 1.25+)
server {
    listen 443 quic reuseport;  # UDP
    listen 443 ssl http2;       # TCP fallback
    ssl_certificate /etc/ssl/cert.pem;
    ssl_certificate_key /etc/ssl/key.pem;
    add_header Alt-Svc 'h3=":443"; ma=86400';
}
✅ 핵심 요약
HTTP/1.1은 텍스트 기반, 순차 처리로 HOL Blocking이 발생한다. HTTP/2는 바이너리 멀티플렉싱과 헤더 압축으로 앱 레벨 HOL를 해결했지만 TCP HOL가 남아있다. HTTP/3는 QUIC(UDP)으로 전환해 모든 HOL Blocking을 제거하고 0-RTT 연결, 연결 마이그레이션을 제공한다. 오늘날 주요 웹사이트의 상당 부분이 이미 HTTP/2 또는 HTTP/3를 사용 중이다.
반응형

댓글