[기술 딥다이브] HTTP/3는 왜 UDP 위에 있는가


한 줄 요약: HTTP/3가 TCP 대신 UDP 위의 QUIC을 쓰는 이유는, 패킷 하나의 손실이 전체 연결을 멈추는 TCP의 헤드오브라인 블로킹을 스트림별로 독립적인 신뢰성으로 해결하기 위해서다.

HTTP는 버전이 올라갈수록 빨라졌습니다. HTTP/1.1에서 HTTP/2(멀티플렉싱)를 거쳐 HTTP/3에 이르렀습니다. 그런데 HTTP/3는 이전 버전과 달리 TCP 대신 UDP 위에서 동작합니다. ’신뢰성이 없는 UDP로 웹을?’이라는 의문이 들 수 있지만, 그럴 만한 이유가 있습니다.

TCP의 고질병: 헤드오브라인 블로킹(HOL blocking)

TCP는 ‘순서 보장’ 전송 프로토콜입니다. 패킷 1, 2, 3을 보냈는데 2가 지연되면, 3은 2가 도착할 때까지 기다립니다. HTTP/2가 여러 요청을 하나의 TCP 연결로 묶어서(멀티플렉싱) 보내더라도, TCP 수준에서 한 패킷이 손실되면 해당 연결의 모든 요청이 멈추어 기다립니다. 이것이 TCP의 헤드오브라인 블로킹입니다. TCP 계층이 ’순서’를 강제하므로, 애플리케이션(HTTP)은 어쩔 수 없습니다.

QUIC: UDP 위에 ‘직접 구현한’ 신뢰성

HTTP/3는 QUIC이라는 전송 프로토콜 위에서 동작합니다. QUIC은 UDP를 사용합니다. UDP 자체는 순서 보장과 재전송 기능이 없지만, QUIC이 그 기능을 애플리케이션 계층에서 직접 구현합니다. 즉 ‘TCP의 역할을 UDP 위에서 다시 만들되, 더 효율적으로’ 설계한 것입니다.

핵심 차이: 스트림마다 독립적인 손실 처리

QUIC은 하나의 연결 안에 여러 스트림을 두되, 각 스트림의 손실 처리가 서로 독립적입니다. 스트림 A의 패킷이 손실되어도 스트림 B와 C는 멈추지 않습니다. TCP처럼 ‘하나가 손실되면 전부 멈추는’ 것이 아니라 ’해당 스트림만 재전송’합니다. 결과적으로 애플리케이션 계층의 HOL 블로킹을 해결합니다.

연결 설정도 빠르다: TLS를 포함한 1-RTT

QUIC은 TLS 1.3을 프로토콜 안에 통합했습니다. 그래서 연결 설정(핸드셰이크와 TLS)을 TCP와 TLS의 조합이 필요한 2~3-RTT에서 1-RTT로 줄였고, 이전 연결 정보가 있으면 0-RTT로 줄입니다. 모바일처럼 왕복 지연(RTT)이 큰 환경에서 체감 속도가 향상됩니다.

연결 마이그레이션: IP가 바뀌어도 연결이 유지된다

QUIC은 연결 식별을 IP 주소가 아니라 연결 ID로 수행합니다. 와이파이에서 LTE로 전환되어 IP가 변경되어도 연결이 유지됩니다. TCP는 IP와 포트가 바뀌면 연결이 끊어졌지만, QUIC은 그렇지 않습니다. 스마트폰으로 웹을 사용할 때 이 점이 체감됩니다.

어떻게 연결되는가

한 줄로 요약하면: TCP는 한 패킷의 손실이 전체 연결을 멈추게(HOL 블로킹) 하지만, QUIC은 UDP 위에서 신뢰성을 ‘스트림별로 독립적으로’ 재구현하여 그 문제를 해결하고, TLS까지 통합하여 연결 설정까지 단축한 전송 프로토콜입니다. ’신뢰성이 없는 UDP’를 사용하되 ’더 효율적으로 재구성한 것’이 HTTP/3의 핵심입니다.

출처: RFC 9114: HTTP/3 · RFC 9000: QUIC · 위키백과: HTTP/3

이미지: Renepick, Wikimedia Commons (CC-BY-SA 3.0) — 원본