수학적 접근

HTTP/1.1, HTTP/2, HTTP/3 본문

개발/네트워크

HTTP/1.1, HTTP/2, HTTP/3

평등수렴 2025. 11. 18. 00:00
반응형

HTTP/1.1

 

브라우저가 한 도메인에 대해 최대 6개의 TCP 연결을 수립할 수 있으며, 각 TCP 연결은 한 번에 하나의 요청/응답만을 처리한다.

 

클라이언트가 서버로부터 20개의 파일을 내려받는 상황을 가정하여 보면,

 

처음에 각 연결을 통해 6개의 파일을 내려받고, 6개의 연결 중 파일 전송이 완료된 연결로부터 계속하여 7번째 파일, 8번째 파일, ..., 20번째 파일을 내려받게 되므로, 지연이 발생한다.

 

만약 제한된 TCP 연결의 수를 늘릴 수 있다면 대기에 의한 지연을 줄일 수 있을 것이다.

 

여기서, 여러 도메인을 통해 웹사이트 표시에 필요한 리소스를 가져오는 도메인 샤딩(Domain Sharding) 기법이 사용된다.

 

<img src="https://cdn1.example.com/image1.jpg">
<img src="https://cdn2.example.com/image2.jpg">
<img src="https://cdn3.example.com/image3.jpg">
...

 

도메인별 TCP 연결 수는 독립적으로 카운트된다.

 

만약 3개의 도메인이 있다면, 최대 18개의 TCP 연결을 수립할 수 있는 것이다.

 

 

참고로 "한 도메인에 대해 최대 6개의 TCP 연결을 수립"은 브라우저에 의한 제한이다.

HTTP/1.1의 공식 명세인 RFC2616의 권고 사항을 보면 아래와 같이 나와 있다.

"A single-user client SHOULD NOT maintain more than 2 connections with any server"

공식 명세에서는 최대 2개를 권장하고 있다.

하지만 각 브러우저들은 연결 수 증가에 따른 성능 향상을 위해 최대 6개의 TCP 연결을 가능하도록 하였고, 이는 브라우저들 간의 암묵적 규칙이 되었다.

 

 

 

 

HTTP/2

 

 

서버-클라이언트 간 하나의 TCP 연결을 수립하며, 여러 파일을 여러 패킷으로 분할하여 동시에 전송한다.

 

하지만 TCP는 순서를 보장하는 프로토콜이므로, 실제로는 하나의 TCP 연결 내에서 순차적으로 처리된다.

 

 

HTTP/1.1에 비해 연결의 수가 적어 연결 오버헤드가 감소하므로, 네트워크 환경이 좋다면 HTTP/1.1보다 빠르게 데이터를 주고받을 수 있다.

 

하지만 패킷 손실률이 1~2% 이상의 좋지 않은 네트워크 환경에서는 오히려 HTTP/1.1보다 느릴 수 있다. 

 

 

패킷 손실은 어떤 과정으로 TCP 통신을 느리게 만들까?


클라이언트가 요청한 아래 파일들을 서버 단에서 전송하는 상황을 보자.

[image1.png]
[app.js]
[style.css]
[image2.jpg]

 

HTTP/2는 각 파일을 여러 패킷으로 나누어 동시에 전송한다.

 

하지만 TCP 연결에서는 각 패킷을 순차적으로 처리한다.

패킷1: (image1.png 일부)
패킷2: (app.js 일부)
패킷3: (style.css 일부)
패킷4: (image1.png 일부)
...

 

위 상황에서 패킷2가 손실되었다고 가정해 보자.

 

앞에서 말했듯이 TCP 프로토콜은 순서를 보장하는 프로토콜이므로, 패킷1~4는 순서대로 클라이언트에 도달하여야 한다.

 

클라이언트의 TCP는 서버에 손실된 패킷2를 재요청한다.

 

패킷 3,4는 클라이언트 TCP 버퍼에 저장되어 있으며, 패킷2가 도달하기 전까지 클라이언트에 도달하지 못한다.

 

 

이러한 문제를 보완하기 위해, 결국 HTTP/2에서도 도메인 샤딩 기법을 사용하기도 한다.

 

 

 

 

여기서 이런 의문이 들었다.

 

사실 웹사이트를 렌더링할 때, image1.png, app.js, style.css 와 같은 파일 중 어느 것이 먼저 다운로드되든 상관이 없고, 이 중 어느 파일이 손실되든 다른 파일은 정상적으로 다운로드될 수 있어야 한다.

 

그런데 왜 HTTP/2는 TCP 프로토콜을 사용하는 비효율을 택했을까?

 

 

 

이에 대한 답은 "관성"이었다.

 

1991년 웹이 처음 만들어지면서 HTTP/0.9 프로토콜이 등장하였을 때에는, 단순한 텍스트 전달이 목적이었다.

 

당시 TCP는 이미 검증되고 신뢰성 있는 프로토콜이었으며, 여기에는 순서 보장 및 신뢰성이 당연히 필요해 보였다.

 

이후로 HTTP/1.0, HTTP/1.1, HTTP/2 프로토콜이 차례로 나왔으나,

 

오랫동안 쌓인 방화벽, 로드밸런서, 라우터 등의 인프라는 위 프로토콜에서 TCP를 계속 채택하도록 만들었다. 

 

 

 

HTTP/3

 

 

HTTP/3에서는 비연결형, 비신뢰성, 빠른 속도를 특징으로 하는 UDP를 기반으로 하는 QUIC 프로토콜을 이용한 통신을 한다.

 

위 도표에서 QUIC에 대한 키워드를 보면, TCP와 유사하다는 것을 알 수 있다.

 

실제로 QUIC는 UDP 위에 다시 TCP를 구현한 것이다.

 

그렇다면 QUIC는 앞선 TCP와 무엇이 다른 것일까?

 

크게 두 가지로 정리할 수 있다.

 

 

1. 프로토콜이 동작하는 영역

 

기존 TCP 프로토콜은 커널(OS) 영역에서 동작한다.

 

따라서 TCP 프로토콜이 업데이트 되려면 커널 수정이 필요, OS가 업데이트되어야 한다.

 

즉, 새로운 TCP 프로토콜을 적용하기 위해 전 세계의 라우터, 방화벽이 업데이트 되어야 한다는 것이다.

 

 

QUIC는 유저(App) 영역에서 동작하여, 브라우저를 업데이트하는 것만으로 프로토콜 업데이트가 가능하다.

 

이를 통해 기존 인프라에 묶여 TCP 프로토콜을 사용할 수 밖에 없었던 한계를 어느 정도 해결하였다.

 

 

2. 여러 개의 스트림

 

QUIC도 TCP와 마찬가지로 순서 보장, 무손실을 보장한다.

 

하지만 앞서 보았던 TCP 통신의 문제를 보완하기 위해 여러 개의 스트림을 사용한다.

 

각 스트림은 독립적인 byte offset을 가짐으로써, 어느 한 스트림에서 발생한 손실은 다른 스트림에 영향을 주지 않는다.

 

 

HTTP/2에서와 마찬가지로 클라이언트가 요구한 아래 파일들을 서버 단에서 전송하는 상황을 보자.

[image1.png]
[app.js]
[style.css]
[image2.jpg]

 

QUIC에는 여러 개의 스트림이 존재하므로, 아래와 같은 방식으로 전송될 수 있다.

스트림1 - 패킷1 (image1.png 일부) ✓, 패킷4 (style.css 일부) ✓ → 전달 완료
스트림2 - 패킷2 (app.js 일부) ✗ → 재전송 중...
스트림3 - 패킷3 (style.css 일부) ✓ → 전달 완료

 

하나의 스트림에서 패킷 손실이 발생하여 재전송 대기 중 상태에 있더라도, 다른 스트림은 독립적으로 데이터를 전송한다.

 

 

그래서 HTTP/3는 HTTP/2보다 빠른가?

 

매우 안정적인 네트워크 환경에서는 UDP 오버헤드로 인해 HTTP/3이 HTTP/2에 비해 미세하게 느리다.

 

하지만 패킷 손실이 발생하는 네트워크 환경에서는 HTTP/3이 HTTP/2에 비해 매우 빠르다.

 

일반적으로 유선 네트워크에 비해 무선 네트워크에서 패킷 손실률이 더 높게 나타나므로, HTTP/3는 모바일 네트워크에 적합한 형태이다.

 

 

 

2019년 HTTP/3가 등장한 이래로 아직까지는 널리쓰이고 있지는 않지만, 빅테크, 스타트업을 중심으로 채택률이 높아지고 있다.

 

2025년 11월 기준으로, 전체 웹사이트의 36.2%가 HTTP/3을 채택하고 있다.

https://w3techs.com/technologies/details/ce-http3 

 

 

HTTP/3의 채택을 저해하는 요인으로는 아래와 같은 것들이 있다.

1. 역사적 배경
- 1990년~2000년대에는 연결 지향/추적 가능한 TCP에 비해, 비연결/추적이 어려운 UDP는 상대적으로 위험하다고 간주되었다. 
- UDP가 악용된 사례가 있다(DDos 공격, DNS Amplification 공격, 악성코드 통신, 데이터 유출 등).
- 위와 같은 이유로, 오래된 방화벽 정책에서는 UDP 443이 차단되어 있는 경우가 있다.

2. 오래된 장비의 한계
- 오래된 라우터 장비에서는 UDP 연결을 Stateless로 간주하여 UDP 포트 맵핑을 30초 정도만 유지하는데, QUIC 연결은 수 분 ~ 수 시간의 연결 유지가 필요하다. 따라서 NAT Timeout이 발생한다.
- 오래된 로드밸런서는 UDP의 비연결성에 따라 매 패킷을 전송하는 서버를 독립적으로 결정하는데, QUIC의 패킷에 포함된 Connection ID로 인해, 같은 Connection ID를 가진 패킷이 서로 다른 서버로 전송되는 경우, 처음 연결을 수립한 서버 외에는 해당 Connection ID를 가진 패킷을 버린다. 따라서 매우 높은 패킷 손실률이 발생한다.

3. 서버 지원 부족
- NginX는 2024년에 이르러서야 프로덕션에서 HTTP/3 사용을 권장하고 있으며, Apache는 아직 실험적 단계이다.
- CDN(cloudflare, fastly, akamai, cloudfront)에서의 HTTP/3 지원이 늦거나 이용률이 저조하다, HTTP/2에서 HTTP/3로의 마이그레이션에 따른 인프라 교체, 엔지니어 교육, 모니터링 시스템 교체 등 소요 비용이 높으나, 이에 비해 HTTP/3에 대한 고객 요구는 낮다.
- 동일 트래픽에 대해 HTTP/3의 CPU 사용량이 HTTP/2에 비해 1.5~2배가량 높다.
- 연결 당 메모리 사용이 HTTP/3이 HTTP/2에 비해 2배 가량 높다.

 

 

반응형
Comments