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/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| 전송 프로토콜 | TCP | TCP | UDP (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 (멀티플렉싱 효과)