본문으로 건너뛰기
김신건의 로그

[Network] HTTP/2: multiplexing, HPACK, server push의 종말

· 수정 · 📖 약 2분 · 678자/단어 #http #network #backend #protocol #multiplexing
HTTP/2, h2, HPACK, stream multiplexing, server push, h2c

정의

HTTP/2 (2015, RFC 9113) 는 HTTP/1.1 의 문법은 유지하되 전송을 바이너리 + 멀티플렉싱 으로 바꾼다. Head-of-Line Blocking (HTTP 레벨) 해결이 핵심.

핵심 변경 3가지:

  1. Binary framing: 텍스트 → 바이너리. 파싱 효율 + 정확성.
  2. Stream multiplexing: 한 TCP 연결에서 여러 stream 병렬.
  3. HPACK 헤더 압축: 반복 헤더의 압축 + 인덱싱.

Binary Framing

HTTP/1.1 의 텍스트 메시지frame 으로 분해:

Frame Type의미
DATA본문
HEADERS헤더
PRIORITY스트림 우선순위
RST_STREAM스트림 취소
SETTINGS연결 설정
PUSH_PROMISEserver push (대부분 비활성)
PINGkeep-alive 측정
GOAWAY연결 종료
WINDOW_UPDATEflow control
CONTINUATION큰 헤더 분할
flowchart LR
    H1["HTTP/1.1 메시지<br/>(텍스트)"] -->|HTTP/2| Frames
    Frames["[HEADERS frame]<br/>[DATA frame]<br/>[DATA frame]"]

Multiplexing

한 TCP 연결에서 여러 stream (요청/응답 쌍)frame 인터리빙 으로 동시 진행:

sequenceDiagram
    autonumber
    participant C as Client
    participant S as Server

    C->>S: HEADERS stream=1 (GET /a)
    C->>S: HEADERS stream=3 (GET /b)
    C->>S: HEADERS stream=5 (GET /c)
    S-->>C: HEADERS stream=3 (작은 응답 먼저)
    S-->>C: DATA stream=3 (완료)
    S-->>C: HEADERS stream=1
    S-->>C: DATA stream=5 (부분)
    S-->>C: DATA stream=1 (부분)
    S-->>C: DATA stream=1 (완료)
    S-->>C: DATA stream=5 (완료)
항목HTTP/1.1HTTP/2
동시 요청N개 TCP 연결1 TCP, N streams
HoL Blocking (HTTP)있음 (pipelining)없음
헤더 압축없음HPACK
Binary텍스트binary

IMPORTANT

Multiplexing 은 HTTP 레벨의 HoL blocking 만 해결. TCP 패킷 손실 이 발생하면 그 아래 모든 stream 이 대기. 이 한계가 HTTP/3 (QUIC) 의 등장 이유.

HPACK 헤더 압축

반복되는 헤더 (User-Agent, Cookie 등) 를 인덱스로 참조. Static Table (61개 미리 정의) + Dynamic Table (연결마다 갱신) + Huffman.

요청 1: :method=GET, :path=/a, user-agent=Mozilla/5.0...
→ 보내고 dynamic table 에 등록 (예: index 62)

요청 2: :method=GET, :path=/b, user-agent=Mozilla/5.0...
→ index 62 만 보냄 (수십 바이트 → 1 바이트)

자세한 건 hpack 참고.

CAUTION

CRIME / BREACH 공격 의 변형 (HPACK 압축 oracle). 일반적으로 안전하지만, 비밀 헤더 + 사용자 입력이 같은 응답 에 들어가면 위험.

Server Push (사실상 폐기)

/index.html 요청에 서버가 미리 /style.css, /app.js 도 push:

sequenceDiagram
    C->>S: GET /index.html
    S-->>C: PUSH_PROMISE /style.css
    S-->>C: PUSH_PROMISE /app.js
    S-->>C: 200 /index.html
    S-->>C: 200 /style.css (요청 없이 미리)
    S-->>C: 200 /app.js (요청 없이 미리)

WARNING

2022 Chrome 이 server push 를 제거. push 캐시 적중률이 낮고 bandwidth 낭비 + priority 충돌. 2026 시점 server push 는 사실상 죽은 기능. 대신 103 Early Hints + <link rel=preload> 패턴.

h2 vs h2c

프로토콜의미
h2TLS 위 HTTP/2 (대부분)
h2ccleartext (내부 네트워크, gRPC mesh)

브라우저는 h2 만. 서버끼리는 h2c 도 흔함 (TLS 종료를 가까운 sidecar/proxy 에서).

Flow Control

스트림 / 연결마다 window size. WINDOW_UPDATEbackpressure. TCP 의 sliding window 와 별개 application 레벨 제어.

flowchart LR
    Server -->|WINDOW_UPDATE +65535| Client
    Client -->|"DATA (window 안에서만)"| Server

흔한 함정

WARNING

  1. 다수 TCP 연결의 습관 = HTTP/2 환경에서 6 connections per origin 같이 옛 패턴을 유지하면 멀티플렉싱 효과 0.
  2. Connection, Upgrade, Proxy-Connection 헤더 = HTTP/2 에서 금지된 헤더. 보내면 연결 RST.
  3. Priority 잘못 설정 = 일부 클라이언트가 priority frame 무시. RFC 9218 의 priority hints 가 더 신뢰.
  4. PUSH 의존 코드 = 위 server push 폐기 때문에 fallback 필수.

관련 위키

이 글의 용어 (7개)
[Network] gRPC: HTTP/2 + Protobuf, 4가지 streaming 패턴network
정의 gRPC 는 HTTP/2 위에서 Protobuf 직렬화 로 동작하는 고성능 RPC 프레임워크. Google 내부 Stubby 의 오픈소스 후계. 핵심 4가지: 1. Prot…
[Network] HTTP/1.1: keep-alive, pipelining, chunked transfernetwork
정의 HTTP/1.1 (1997, RFC 9112 으로 재정리) 는 텍스트 기반 stateless request/response 프로토콜. 2026 시점에도 대부분의 트래픽이 H…
[Network] HTTP/3: QUIC 위의 HTTP, 0-RTT, connection migrationnetwork
정의 HTTP/3 (2022, RFC 9114) 는 HTTP 의 전송 레이어를 TCP → QUIC 으로 교체한 버전. UDP 위에 QUIC, QUIC 위에 HTTP. 핵심 동기:…
Head-of-Line Blockingnetwork
정의 Head-of-Line Blocking (HOLB) 은 처리 순서가 정해진 큐에서 맨 앞 항목의 지연이 그 뒤 항목 전체의 지연으로 전파되는 현상이다. 네트워크 프로토콜에서…
HPACKnetwork
정의 HPACK (RFC 7541)은 HTTP/2 에서 요청·응답 헤더를 압축하기 위해 설계된 방식. HTTP/1.1 의 헤더는 매 요청마다 텍스트로 반복 전송되었다 (한 페이지…
TCPnetwork
정의 TCP (Transmission Control Protocol)는 신뢰성 있는 연결 지향 전송 계층 프로토콜이다. RFC 9293 으로 정의되어 있다. HTTP/1.1·2,…
TLS / SSLnetwork
정의 TLS (Transport Layer Security)는 (또는 위 ) 위에서 동작하는 암호화·인증 프로토콜이다. SSL 은 TLS 의 전신 (Netscape 1995, 더…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기