본문으로 건너뛰기

HTTP/2·HTTP/3 설정: 멀티플렉싱과 QUIC

HTTP/2는 단일 연결에서 여러 요청을 동시에 처리하는 멀티플렉싱으로 HTTP/1.1 대비 페이지 로딩 성능을 2~3배 개선합니다. HTTP/3는 UDP 기반 QUIC 프로토콜로 패킷 손실 환경에서도 성능을 유지합니다.


HTTP/1.1 vs HTTP/2 vs HTTP/3 비교

HTTP 버전 비교

항목HTTP/1.1HTTP/2HTTP/3
전송 프로토콜TCPTCPUDP (QUIC)
멀티플렉싱❌ (HOL 블로킹)✅ (단일 TCP 스트림)✅ (독립 QUIC 스트림)
헤더 압축✅ (HPACK)✅ (QPACK)
서버 푸시✅ (실용성 낮음)❌ (제거됨)
TLS 필수사실상 필수✅ 필수
0-RTT 연결

Nginx HTTP/2 활성화

# Nginx 1.25.1 이상: http2 on 지시어 사용
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on; # HTTP/2 활성화
server_name example.com;

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;

location / {
proxy_pass http://backend;
proxy_http_version 1.1; # 백엔드와는 HTTP/1.1 사용 (일반적)
proxy_set_header Connection "";
proxy_set_header Host $host;
}
}

# Nginx 1.25.1 미만 (구버전): listen에 http2 추가
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
# ...
}
# HTTP/2 적용 확인
curl -I --http2 https://example.com | grep "HTTP/"
# HTTP/2 200

# 또는 h2 프로토콜 확인
openssl s_client -connect example.com:443 -alpn h2 2>/dev/null | grep "ALPN"
# ALPN protocol: h2 ← HTTP/2 협상됨

HTTP/2 성능 튜닝

http {
# HTTP/2 동시 스트림 수 (기본: 128)
http2_max_concurrent_streams 256;

# 초기 윈도우 크기 (클수록 처리량 증가, 메모리 증가)
# http2_body_preread_size 64k; # Nginx 1.25.1+

# 유휴 연결 타임아웃
keepalive_timeout 65;
keepalive_requests 1000;
}

Apache HTTP/2 활성화 (mod_http2)

# Ubuntu
sudo a2enmod http2
sudo systemctl restart apache2

# mod_http2 설치 확인
apache2ctl -M | grep http2
# http2_module (shared)
# /etc/apache2/conf-available/http2.conf

# 전역 또는 VirtualHost에 설정
Protocols h2 h2c http/1.1
# h2 : HTTP/2 over TLS
# h2c : HTTP/2 cleartext (HTTP, 브라우저는 지원 안 함)
# http/1.1 : 폴백

# Apache MPM: HTTP/2는 Event MPM 권장 (Prefork는 미지원)
# sudo a2dismod mpm_prefork
# sudo a2enmod mpm_event
<VirtualHost *:443>
ServerName example.com

SSLEngine On
SSLCertificateFile /etc/ssl/example.com/fullchain.pem
SSLCertificateKeyFile /etc/ssl/example.com/privkey.pem

Protocols h2 http/1.1

# HTTP/2 push (선택적, 실용성 낮음)
# H2PushResource /static/app.css
# H2PushResource /static/app.js
</VirtualHost>

HTTP/3 (QUIC) 설정

HTTP/3는 Nginx 1.25.x 이상에서 실험적으로 지원됩니다. OpenSSL 대신 BoringSSL이나 quictls가 필요합니다.

# Nginx에서 HTTP/3 지원 여부 확인
nginx -V 2>&1 | grep "with-http_v3_module"
server {
# HTTP/3 리스너 (UDP 포트 443)
listen 443 quic reuseport;
listen 443 ssl;
listen [::]:443 quic reuseport;
listen [::]:443 ssl;
http2 on;

server_name example.com;

ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/privkey.pem;
ssl_protocols TLSv1.3; # HTTP/3는 TLS 1.3 필수

# Alt-Svc 헤더: HTTP/3 지원 안내 (브라우저가 다음 요청부터 QUIC 사용)
add_header Alt-Svc 'h3=":443"; ma=86400';

location / {
proxy_pass http://backend;
}
}
# HTTP/3 동작 확인
curl -I --http3 https://example.com | grep "HTTP/"
# HTTP/3 200

클라이언트와 백엔드 간 프로토콜 전략

upstream backend {
server app1:8080;
server app2:8080;

# Nginx → 백엔드는 대부분 HTTP/1.1 사용
# 백엔드가 HTTP/2 gRPC라면 grpc_pass 사용
keepalive 64;
}

server {
listen 443 ssl;
http2 on;

# 일반 HTTP 백엔드
location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}

# gRPC 백엔드 (HTTP/2)
location /grpc/ {
grpc_pass grpc://grpc_backend:50051;
}
}

HTTP/2 서버 푸시 (Server Push)

HTTP/2는 서버가 요청 없이 리소스를 선제적으로 전송할 수 있습니다. 그러나 실용성이 낮아 HTTP/3에서 제거됩니다.

location = /index.html {
proxy_pass http://backend;

# HTML 요청 시 CSS, JS도 함께 푸시 (HTTP/2 only)
http2_push /static/app.css;
http2_push /static/app.js;
}

# 또는 Link 헤더로 동적 푸시
location / {
proxy_pass http://backend;
http2_push_preload on;
# 백엔드가 다음 헤더를 반환하면 자동 푸시:
# Link: </static/app.css>; rel=preload; as=style
}

현실적인 대안: <link rel="preload"> 태그로 브라우저 힌트만 주는 것이 더 안정적입니다.


HTTP/2 도입 효과 측정

# HTTP/1.1 성능 측정
ab -n 1000 -c 50 https://example.com/

# HTTP/2 성능 측정 (h2load 사용)
h2load -n 1000 -c 50 -m 10 https://example.com/
# -m 10 : 연결당 최대 10 동시 스트림

# h2load 설치
sudo apt install nghttp2-client

# 결과 비교
# HTTP/1.1: requests/sec ~200
# HTTP/2: requests/sec ~800 (멀티플렉싱 효과)