업데이트됨 1개월 전
50년 동안 TCP는 간단한 약속으로 인터넷을 지탱해왔습니다: 바이트는 순서대로 도착하거나, 아예 도착하지 않거나. 이 보장이 TCP를 신뢰할 수 있게 만들었습니다. 동시에 TCP를 병목 지점으로 만들기도 했습니다.
HTTP/3는 TCP를 완전히 버립니다. 대신 QUIC을 사용합니다—TCP가 설계상 해결할 수 없는 문제들을 풀기 위해 만들어진 새로운 전송 프로토콜입니다.
TCP가 고칠 수 없는 문제
HTTP/2는 멀티플렉싱을 도입했습니다: 여러 요청이 하나의 연결을 공유하는 방식입니다. 열 개의 이미지를 별도의 연결 열 개가 아니라 하나의 TCP 연결로 동시에 불러오는 것입니다. 효율적입니다.
하지만 TCP는 바이트만 봅니다. 이미지나 요청이나 스트림 같은 건 모릅니다. TCP가 아는 것은: 바이트 41은 바이트 42 앞에 오고, 바이트 42는 바이트 43 앞에 온다는 것입니다. 언제나. 예외 없이.
패킷 42가 네트워크에서 손실되면, TCP는 기다립니다. 패킷 43부터 100까지는 성공적으로 도착했을 수 있지만, TCP는 패킷 42가 재전송될 때까지 그것들을 붙잡아 둡니다. 애플리케이션은 그것들을 건드릴 수 없습니다.
이것이 바로 헤드-오브-라인 블로킹입니다. 패킷 42에 이미지 5의 데이터가 들어 있다면, 이미지 6부터 10까지는 기다립니다—그들의 데이터가 온전히 도착했음에도 불구하고. TCP의 가장 큰 강점이 가장 큰 약점이 되어버린 것입니다: 바이트가 순서대로 도착한다는 보장이, 모든 스트림이 다른 스트림의 문제를 기다려야 한다는 약속이 되었습니다.
TCP 안에서는 이것을 고칠 수 없습니다. 순서 보장이 곧 TCP이기 때문입니다. 그것을 제거하면 다른 프로토콜이 됩니다.
그래서 다른 프로토콜을 만들었습니다.
QUIC이란 무엇인가
QUIC은 UDP 위에 구축되어 있습니다. UDP는 거의 아무것도 보장하지 않습니다—패킷이 도착할 수도 있고, 안 할 수도 있고, 순서 없이 도착할 수도 있습니다. 다운그레이드처럼 들립니다. 실제로는 자유입니다.
UDP는 아무것도 강요하지 않습니다. 이 단순함 덕분에 QUIC은 현대 애플리케이션에 필요한 것을 정확하게 구현할 수 있습니다:
네이티브 스트림이 전송 계층에 존재합니다. QUIC은 스트림 5와 스트림 6이 독립적이라는 것을 압니다. 스트림 5가 패킷을 잃으면, 스트림 6은 중단 없이 계속됩니다. 헤드-오브-라인 블로킹은 연결 전체가 아니라 스트림 단위로만 발생합니다.
내장 암호화로 TLS가 필수이자 핵심입니다. 암호화되지 않은 QUIC은 없습니다. 핸드셰이크가 전송 설정과 암호화 설정을 하나의 교환으로 통합합니다.
연결 ID가 IP 주소와 독립적으로 연결을 식별합니다. 이것은 들리는 것보다 훨씬 중요합니다.
핸드셰이크의 혁명
TCP + TLS는 마치 구애 의식 같은 절차가 필요합니다:
- TCP SYN
- TCP SYN-ACK
- TCP ACK
- TLS ClientHello
- TLS ServerHello와 인증서
- TLS Finished
- 마침내, 실제 요청
단 하나의 애플리케이션 데이터 바이트가 흐르기 전에 최소 두 번의 왕복이 필요합니다.
QUIC은 모든 것을 통합합니다. 클라이언트가 TLS를 포함한 초기 매개변수를 하나의 패킷으로 보냅니다. 서버는 자신의 매개변수로 응답하고 핸드셰이크를 완료합니다. 한 번의 왕복. 애플리케이션 데이터가 즉시 흐릅니다.
재방문자에게 QUIC은 더 놀라운 것을 제공합니다: 왕복이 필요 없습니다. 클라이언트는 이전 연결의 매개변수를 사용해 첫 번째 패킷부터 암호화된 애플리케이션 데이터를 보냅니다. 서버는 즉시 애플리케이션 데이터로 응답합니다.
이것은 트레이드오프를 이해하기 전까지는 마법처럼 들립니다: 서버는 그 첫 번째 패킷이 새로운 것인지 어제 요청의 재전송인지 알 수 없습니다. 0-RTT 데이터는 공격자에 의해 재전송될 수 있습니다. 반복해도 해가 없는 멱등성 요청만 0-RTT를 사용해야 합니다.
연결 마이그레이션
TCP 연결은 네 가지로 정의됩니다: 출발지 IP, 출발지 포트, 목적지 IP, 목적지 포트. 이 중 하나만 바뀌어도 연결이 끊어집니다.
집에서 화상 통화를 하고 있습니다. 밖으로 나갑니다. 휴대폰이 WiFi에서 셀룰러로 전환됩니다. IP 주소가 바뀝니다. TCP 연결이 끊어집니다. 화상 통화 앱은 재연결하고, TLS를 다시 협상하고, 상태를 복원해야 합니다.
QUIC 연결은 연결 ID를 사용합니다. IP 주소가 바뀌어도 연결 ID는 바뀌지 않습니다. 새로운 IP 주소에서 같은 연결 ID로 패킷을 보냅니다. 서버가 여러분을 알아봅니다. 화상 통화가 중단 없이 계속됩니다.
이것은 네트워크 사이를 끊임없이 이동하는 모바일 사용자에게 혁신적입니다. 예전이라면 연결이 끊어졌을 상황에서도 이제는 살아남습니다.
기반으로서의 보안
TCP는 암호화를 선택 사항으로 봅니다—원하면 위에 덧붙이는 것. QUIC은 암호화를 필수로 봅니다.
모든 QUIC 패킷은 TLS 1.3으로 암호화됩니다. 페이로드만이 아닙니다—대부분의 헤더 필드도 암호화됩니다. 네트워크 장비는 TCP에서처럼 QUIC 트래픽을 검사하거나 조작할 수 없습니다.
이것은 프라이버시를 향상시킵니다. 또한 고착화를 막습니다—중간 장치들이 프로토콜 내부 구조에 의존하기 시작해 프로토콜 발전이 불가능해지는 문제입니다. QUIC의 암호화된 헤더는 오직 통신 양 끝단만이 해석할 수 있도록 보장합니다.
HTTP/3: QUIC 위의 HTTP
HTTP/3는 HTTP의 핵심—메서드, 헤더, 상태 코드—을 TCP 대신 QUIC을 통해 전송하는 것입니다.
전환 방식은 간단합니다: 각 HTTP 요청이 별도의 QUIC 스트림을 사용합니다. 헤더 압축(QPACK)이 HTTP/2의 HPACK을 대체하며, 순서 없이 도착할 수 있는 스트림에 맞게 재설계되었습니다.
HTTP/3는 HTTP/2에서 너무 복잡하고 활용이 저조했던 서버 푸시를 제거합니다. 실제로 효과가 입증된 것을 바탕으로 우선순위 신호를 단순화합니다.
변경 사항은 전송 계층에 있습니다. 애플리케이션 코드는 거의 수정이 필요 없습니다.
실제 성능 수치
좋은 네트워크에서: HTTP/2보다 5~10% 빠릅니다. 핸드셰이크 개선이 의미 있지만, TCP도 안정적인 네트워크에서는 꽤 잘 동작합니다.
손실이 있는 네트워크에서: 20~30% 빠릅니다. 이것이 QUIC이 빛을 발하는 환경입니다. 패킷 손실이 더 이상 스트림 전체로 번지지 않습니다. 불안정한 연결을 쓰는 모바일 사용자들이 가장 큰 이점을 얻습니다.
연결 마이그레이션은 단순한 벤치마크에서는 측정되지 않는 이점을 제공합니다. 네트워크를 이동하는 사용자들은 재연결 대신 연속성을 경험합니다.
도입이 느린 이유
UDP는 평판 문제가 있습니다. 기업 방화벽은 종종 UDP를 차단합니다. 공용 네트워크는 속도를 제한합니다. 과거의 남용(DNS 증폭 공격, UDP 플러드)이 네트워크 운영자들을 경계하게 만들었습니다.
HTTP/3는 UDP가 안 되면 HTTP/2로 폴백합니다. 우아한 저하이지만, 이점은 사라집니다.
QUIC 구현은 TCP보다 어렵습니다. TCP에는 수십 년간 쌓인 최적화가 있으며, 상당 부분이 하드웨어 가속이 있는 커널 코드에 자리합니다. QUIC은 사용자 공간에서 실행되며, TCP가 하드웨어에 위임하는 암호화를 직접 처리합니다. CPU 부담이 더 크지만, 구현이 성숙해짐에 따라 격차는 줄어들고 있습니다.
디버깅 도구도 아직 따라오지 못했습니다. tcpdump와 Wireshark는 TCP를 깊이 이해합니다. QUIC 지원은 있지만 깊이가 부족합니다. 네트워크 운영자들은 암호화된 QUIC 패킷 안을 들여다볼 수 없습니다—프라이버시 기능이 동시에 디버깅의 장벽이기도 합니다.
현재 상황
모든 현대 브라우저가 HTTP/3를 지원합니다. Chrome, Firefox, Safari, Edge—모두.
주요 CDN들이 HTTP/3를 제공합니다: Cloudflare, Fastly, Akamai, Amazon CloudFront. Google, Facebook, 그리고 현대 웹의 상당 부분이 이를 사용합니다.
현재 추정치: 웹 트래픽의 25~30%가 HTTP/3를 사용하며, 계속 증가 중입니다.
HTTP/3 지원 여부는 Alt-Svc 헤더(서버가 HTTP/3 가용성을 알림) 또는 DNS HTTPS 레코드(첫 연결 시 DNS에서 확인)를 통해 알려집니다. 둘 다 우아한 폴백을 지원합니다.
더 넓은 의미
QUIC은 인터넷의 근본적인 프로토콜도 교체될 수 있음을 증명합니다. TCP는 영구적인 것처럼 보였습니다—너무 깊이 자리 잡아서 변화가 불가능한 것처럼. QUIC은 그렇지 않음을 보여줬습니다.
접근 방식 자체가 의미 있습니다: UDP 위에 구축하고, 모든 것을 사용자 공간에서 구현하고, 중간 장치들이 구현 세부 사항에 고착될 수 없도록 모든 것을 암호화합니다. 진화가 다시 가능해집니다.
QUIC은 이미 HTTP 외의 용도로 확장되고 있습니다. DNS over QUIC. 실시간 애플리케이션을 위한 WebTransport. 네이티브 스트림, 빠른 핸드셰이크, 연결 마이그레이션의 이점은 광범위하게 적용됩니다.
수십 년간 멈춰 있던 인터넷의 전송 계층이 다시 움직이고 있습니다.
HTTP/3와 QUIC에 관한 자주 묻는 질문
완전히 새로운 프로토콜을 만드는 대신 UDP 위에 구축한 이유는 무엇인가요?
UDP는 이미 어디에나 있습니다. 라우터, 방화벽, NAT 장치들은 UDP 패킷 처리 방법을 알고 있습니다. 새로운 IP 프로토콜을 만들면 전 세계 네트워크 인프라를 변경해야 합니다—최소 10년이 걸리는 작업입니다. UDP는 지금 당장 작동하는 기반을 제공하면서, QUIC이 필요한 것을 정확하게 구현할 수 있는 자유를 줍니다.
네트워크가 UDP를 차단하면 HTTP/3를 사용할 수 있나요?
브라우저가 자동으로 TCP 기반 HTTP/2나 HTTP/1.1로 폴백합니다. 오류 메시지는 보이지 않습니다—HTTP/3의 이점을 누리지 못할 뿐입니다. 이런 우아한 저하 덕분에 HTTP/3 배포가 기존 환경을 망가뜨리지는 않지만, 제한적인 네트워크에서는 성능 향상을 기대할 수 없습니다.
HTTP/3가 항상 HTTP/2보다 빠른가요?
대체로 그렇지만, 안정적인 네트워크에서는 극적인 차이가 나지 않습니다. 가장 큰 이점은 패킷 손실이 많은 연결이나 네트워크를 이동하는 모바일 사용자에게서 나타납니다. 패킷 손실이 적은 안정적인 유선 연결에서는 소폭의 개선만 볼 수 있습니다. 이 프로토콜은 조건이 완벽하지 않을 때 진가를 발휘합니다.
HTTP/3를 쓰려면 웹사이트 코드를 바꿔야 하나요?
거의 그럴 필요가 없습니다. HTTP/3는 애플리케이션 계층이 아닌 전송 계층을 변경합니다. HTML, JavaScript, API, 서버 로직은 그대로입니다. HTTP/3를 지원하는 서버 소프트웨어가 필요하지만, 애플리케이션 코드는 대부분 수정이 필요 없습니다.
모든 요청에 0-RTT 재개를 사용하지 않는 이유는 무엇인가요?
0-RTT 데이터는 공격자에 의해 재전송될 수 있습니다. 첫 번째 요청이 "1,000달러 이체"였다면, 재전송된 패킷이 돈을 두 번 이체할 수 있습니다. GET 요청처럼 반복해도 아무 문제가 없는 멱등성 요청만 0-RTT를 사용해야 합니다. 부작용이 있는 POST 요청이나 그 외의 요청은 전체 핸드셰이크를 기다려야 합니다.
이 페이지가 도움이 되었나요?