HTTP/1.1 · HTTP/2 · HTTP/3 무엇이 달라졌나

keep-alive, 헤드 오브 라인 블로킹, 멀티플렉싱, QUIC/UDP 등 HTTP 버전별 변화와 실무에 미치는 영향을 설명합니다.

HTTP는 같은 의미론(메서드·상태 코드·헤더)을 유지하면서도, 그 아래 '전송 방식'을 세 번에 걸쳐 크게 바꿔 왔습니다. HTTP/1.1, HTTP/2, HTTP/3은 요청·응답의 의미는 같지만, 네트워크 위에서 데이터를 나르는 방식이 달라 성능 특성이 크게 다릅니다.

HTTP/1.1: keep-alive와 그 한계

HTTP/1.1은 keep-alive(지속 연결)를 도입해, 요청마다 TCP 연결을 새로 맺지 않고 하나의 연결을 재사용할 수 있게 했습니다. 하지만 한 연결에서는 요청을 한 번에 하나씩 처리해야 했습니다(파이프라이닝은 사실상 실패). 그래서 앞선 요청의 응답이 늦으면 뒤 요청이 줄줄이 막히는 헤드 오브 라인 블로킹(Head-of-Line Blocking)이 발생합니다. 브라우저는 이를 우회하려고 도메인당 6개 안팎의 연결을 동시에 열었고, 이 때문에 파일을 여러 도메인에 쪼개는 '도메인 샤딩' 같은 편법이 유행했습니다.

HTTP/2: 멀티플렉싱

HTTP/2의 핵심은 멀티플렉싱(multiplexing)입니다. 하나의 TCP 연결 위에서 여러 요청·응답을 스트림(stream)으로 나눠 동시에 주고받습니다. 더 이상 요청이 한 줄로 서서 기다리지 않으므로, HTTP 계층의 헤드 오브 라인 블로킹이 사라집니다. 여기에 헤더를 압축하는 HPACK과 서버가 리소스를 미리 밀어주는 서버 푸시(현재는 대부분 폐기)가 더해졌습니다.

그런데 HTTP/2에는 남은 함정이 있습니다. 멀티플렉싱은 HTTP 계층의 블로킹은 없앴지만, 그 아래 TCP 계층에서는 여전히 헤드 오브 라인 블로킹이 남습니다. 패킷 하나가 유실되면 TCP는 순서 보장을 위해 그 패킷이 재전송될 때까지 뒤따르는 모든 스트림의 데이터를 붙잡아 둡니다. 여러 스트림이 하나의 TCP 연결을 공유하기 때문에, 손실 하나가 무관한 스트림까지 멈추게 하는 것입니다.

HTTP/3: QUIC과 UDP

HTTP/3은 이 TCP의 한계를 아예 전송 계층을 바꿔 해결합니다. TCP 대신 QUIC이라는 새 프로토콜 위에서 동작하며, QUIC은 UDP 위에 구축됩니다. QUIC은 스트림을 전송 계층에서 독립적으로 관리하기 때문에, 한 스트림에서 패킷이 유실돼도 다른 스트림은 영향받지 않습니다 — TCP의 헤드 오브 라인 블로킹이 근본적으로 사라집니다.

HTTP/1.1  ->  TCP
HTTP/2    ->  TCP        (multiplexed streams, TCP HOL blocking remains)
HTTP/3    ->  QUIC -> UDP (per-stream loss recovery, no TCP HOL)

실무에 미치는 영향

버전이 올라갈수록 손이 덜 가면서 빨라진다는 것이 실무의 요점입니다. HTTP/2·HTTP/3에서는 멀티플렉싱 덕분에 도메인 샤딩·스프라이트·과도한 파일 번들 결합 같은 HTTP/1.1 시대의 최적화가 오히려 역효과일 수 있습니다. 대부분의 CDN·서버가 HTTP/2를 기본 지원하고 HTTP/3도 빠르게 확산 중이므로, 개발자가 할 일은 주로 TLS(HTTPS)를 켜고 최신 버전을 활성화하는 것입니다. 참고로 HTTP/2·HTTP/3은 사실상 HTTPS를 전제로 하므로, 최신 프로토콜을 쓰려면 TLS가 필수입니다.