Easy Understanding

HTTP/3와 QUIC 요약정리 본문

Dev

HTTP/3와 QUIC 요약정리

appleg1226 2022. 6. 24. 17:07

새로운 버전의 HTTP 버전인 HTTP/3 가 이번 2022년 6월 6일에 국제 인터넷 표준화 기구에 표준으로서 등록되었다는 소식을 최근 팀 채널을 통해서 알게 되었습니다.

취준 시절 아래의 다람쥐가 그려져 있는 ‘HTTP 완벽 가이드’라는 책을 읽었는데,

이 책이 쓰여졌을 때는 HTTP/2가 최신 기술이다보니 가볍게만 다루고 있었습니다.

그래서 ‘HTTP/2는 아직까지는 널리 사용되고 있는 기술까지는 아니구나’ 라는 생각도 하고 있었던 차였습니다.

 

심지어 취업을 하고도 이 HTTP/2 와 관련된 스펙에 대해서 접해볼 일이 별로 없었던 것 같습니다.

 

물론 어플리케이션 레벨을 개발하는 입장에서 TCP, UDP, Http 같은 프로토콜을 직접 다뤄볼 기회가 얼마냐 있겠냐만,

그럼에도 불구하고 모든 통신이 이 프로토콜들 위에서 돌아가고 있기에

이번 기회에 HTTP/3 와 그 기반을 이루는 QUIC 프로토콜에 대해서 정리를 해보려고 합니다

 


What is QUIC?

일단 지금 설명드릴 HTTP/3QUIC이라는 프로토콜에 대해서 간단한 소개를 드리려고 합니다.

우선 HTTP/3와 QUIC은 이번 새로운 표준에서 거의 셋트라고 생각하시면 됩니다.

굳이 말하자면 QUIC 때문에 HTTP/3 가 등장하게 되었으니, QUIC이 형 정도는 되는 것 같네요.

 

QUICQuick Udp Internet Connection 이라는 이름으로 처음엔 지어졌다는데,

막상 공식 문서에는 quick 이라는 단어가 코빼기도 보이지 않더라구요.

RFC 9000 - QUIC: A UDP-Based Multiplexed and Secure Transport

위의 문서 링크에도 언급되어 있지만 QUIC을 간단하게 설명하자면 다음과 같습니다.

A UDP-Based Multiplexed and Secure Transport
(UDP를 베이스로 한 멀티플렉스와 보안을 지원하는 프로토콜)

참고로 발음은 '퀵' 입니다.

 

위에서 설명했다시피 QUIC은 UDP를 이용하는 새로운 프로토콜입니다.

오잉? 웬 UDP를 갑자기 사용한다는 거지?

라는 생각이 저는 처음에 들더라구요.

뒤에 설명을 더 해보겠지만, 이건 제가 무지해서 그랬던걸로 결론이 나버렸습니다…

 

놀랍게도 이미 QUIC 프로토콜과 HTTP/3 는 저희가 이미 많이 사용하고 있는 상황인데요,

구글에 이미 도입이 되어있기 때문입니다.

 

 

이미 구글에서는 모든 프로토콜을 QUIC 기반의 HTTP/3(=h3) 로 사용하는 중입니다.

물론 그 이유는 구글에서 QUIC을 만들었기 때문입니다.

 

하지만 이외에도 Facebook, 나무위키(?) 등의 서비스에서 이미 HTTP/3 를 사용하고 있는 것을 확인할 수 있습니다.

(나무위키는 Cloudflare의 CDN을 사용하고 있어서 그런듯 하네요)

 

그렇다면 도대체 이 HTTP/3와 QUIC은 어떤 기술이길래

제대로 사용된지 얼마 되지도 않은 HTTP/2를 벌써부터 대체하겠다고 이렇게 공격적으로 적용되고 있는 걸까요?

 


기존 HTTP와의 비교

위의 그림은 HTTP/2와 QUIC을 사용한 HTTP/3 에 대한 구조를 비교하고 있습니다.

 

먼저 그림에서 공통점을 찾아보면 둘 다 ‘제공하고 있는 기능은 비슷하다’는 것을 확인할 수 있습니다.

HTTP/2에서 제공하던 것은 HTTP/3에서도 기본적으로 모두 지원된다는 것을 볼 수 있습니다.

 

반면 다른 점이라면 네트워크의 계층이 QUIC을 중심으로 재배치 된 것을 확인할 수가 있는데요,

왼쪽의 기존 TCP와 HTTP가 처리하고 있던 것들을

오른쪽에 보면 대부분 QUIC이 가져가 버린 것을 확인할 수 있습니다.

 

TCP의 기능은 거의 대부분 가져왔으며, HTTP/2 에서는 Streaming이 넘어온 것을 볼 수 있습니다.

또한 TLS가 하나의 Layer가 아닌 QUIC의 기본 스펙에 포함되어 있는 것도 확인할 수 있습니다.

QUIC은 그 자체만으로 정말 많은 일들을 처리하도록 설계가 된 것 같습니다.

 


TCP에서 UDP로 넘어온 이유

QUIC과 HTTP/3 - 1. UDP기반 전송 프로토콜의 대두 (해당 문서를 많이 참고하여 작성했습니다)

 

TCP는 우리의 인터넷 통신을 오랜 시간 동안 안정적으로 지탱해준 좋은 프로토콜입니다.

하지만 반대로 생각해보면 오래 되었기 때문에 뭔가 문제가 존재하지 않을까라는 생각도 드는데요.

실제로 TCP는 이미 한계를 보이고 있는 프로토콜입니다.

 

TCP의 경우 이미 많은 기능을 제공하고 있는 프로토콜이었으며,

그 다양한 기능들은 TCP의 헤더를 통해서 이루어지고 있었습니다.

하지만 그 헤더가 많은 곳에서 사용되고 있기 때문에 이젠 더 이상 커스터마이징 할 수 있는 여유가 남아있지가 않은 상황입니다.

그럼 TCP가 아닌 다른 프로토콜을 사용하면 되는데,

현실적으로 TCP, UDP가 아닌 다른 프로토콜을 도입하는 것은 굉장히 어렵습니다.

왜냐하면 대부분의 네트워크 장비들이 TCP, UDP만을 지원하고 있기 때문입니다.

소프트웨어도 아니고 하드웨어 장비들이 이미 이렇게 구축되어 있는 상황에서

새로운 프로토콜이 갑작스럽게 도입된다면 세계 곳곳에서 장애가 뻥뻥 터질 겁니다.

 

하지만 UDP는 신뢰할 수 없고, 비연결성 프로토콜인걸로 알고있는데 어떡하지?

라고 생각했지만 이건 UDP를 모르기 때문에 했던 생각이었습니다.

UDP는 내부가 비어있어서 그런 기능을 하지 못할 뿐입니다.

 

오히려 UDP는 사용하고자 하면 그 비어있는 공간들을 커스텀하여 사용할 수 있는 프로토콜입니다.

지금까지 그 거대한 힘을 숨기고 있던 걸까요…

 

이미 UDP는 기존 네트워크 장비들에도 제약사항이 없으니 TCP를 대체하는 가장 합리적인 대체제라고 할 수 있는 것 같습니다.

그래서 QUIC이 탄생한게 아닐까요?

 


QUIC의 특징과 장점

다음은 UDP를 업은 QUIC이 기존 HTTP/2 등과 비교하여 어떤 점들이 향상되었고,

어떤 기능을 새로 제공하는지 대표적인 것들 몇 가지를 정리해 보았습니다.

1. 개선된 멀티플렉싱

QUIC은 기존의 HTTP/2와 동일하게 멀티플렉싱을 제공하지만 그 방식이 약간 다릅니다.

HTTP/2의 멀티플렉싱은 다음 그림과 같이 동작합니다.

 

녹색과 빨간색은 각 리소스에 대한 스트림인데, 막상 병렬로 동작되는 것 같지만

HTTP/2에서는 내부적으로 하나의 커넥션을 같이 사용하며 번갈아가면서 패킷이 전달되는 형태를 가지고 있습니다.

 

마치 node.js가 싱글스레드로 비동기를 처리하는 것과 비슷한 방식이라고 볼 수 있을 것 같네요.

이 방식의 문제는 결국 하나의 커넥션만 가지고 있기 때문에,

중간에 패킷 하나가 손실이 되면 같은 TCP 커넥션에 포함되어 있던 다른 리소스의 전송에도 지연이 생긴다는 것입니다.

이런 현상을 HOLB(head-of-line-blocking) 현상이라고 부릅니다.

 

하지만, QUIC은 아래 그림에서 보이는 것과 같이 멀티스레드처럼 아예 나눠져서 리소스를 전달합니다.

 

한 스트림의 손실이 다른 스트림에 영향을 주지 않는다는 점에서 HOLB 현상은 해결되었습니다.

이 정도만 되어도 HTTP/2보다 좋은 신뢰성을 가지고 있다고 보여집니다.

QUIC은 HOLB 라는 기존 HTTP의 흠집도 제거해 줌으로서 멀티플렉싱에 대해서 꽤나 완성도 있는 결과를 보여주었습니다.

 

2. 핸드셰이크 시간 감소

TCP를 사용하지 않으니 자연스럽게 QUIC에서는 기존의 3 way Handshake도 개선할 수 있게 되었습니다.

사진만 봐도 알겠지만, TCP+TLS 를 포함한 방식에서 벗어나 더 빠른 방법을 도입할 수 있게 되었습니다.

 

기존에는 TCP 핸드셰이크에 더불어 TLS 핸드셰이크까지 하느라 N번의 Round Trip을 겪어야 하는 구조였습니다.

하지만 어차피 보낼 거 한 번에 보내서 한 번에 끝내버리자는 게 QUIC 입니다.

 

QUIC은 연결은 단 1 RTT(Round Trip Time)으로 끝낼뿐 아니라,

심지어 핸드셰이크가 끝나기 전에 데이터도 미리 보내버립니다.

지금까지 당연히 핸드셰이크는 여러 번 왔다갔다 해야하는 줄로만 알았는데,

너무나도 TCP를 당연하게 여겨서인지

TLS까지 포함해서 한 번만으로 커넥션을 맺을 수 있다는 걸 이번에 처음 알게 되었습니다.

 

추가적으로 QUIC에서는 이렇게 맺어둔 연결을 캐싱하여 추후 다시 요청이 들어왔을 때는

핸드셰이크 없이 0 RTT로 통신하도록 제공하기도 합니다.

 

3. 커넥션 유지를 위한 Connection ID의 등장

QUIC의 헤더에는 Connection ID라는 값이 있으며,

이것을 통해 Connection을 관리하게 됩니다.

 

Connection ID는 IP와는 다르게 클라이언트에서 요청을 시작할 때 생성하는 값인데,

ID 값을 이용해서 다양한 것들을 할 수가 있습니다.

특히 대부분의 문서들에서 이 기능이 Wifi ↔ 셀룰러 데이터가 전환할 때 IP가 바뀌어도 이 Connection을 잃지 않을 수 있도록 할 수 있다고 설명하고 있습니다.

그런데 진짜 이것만을 위해서 이 기능을 만들었을 것 같지는 않고,

이 아이디를 이용한다면 다양한 용도로 쓰일 수 있지 않을까 생각도 듭니다.

 


현재 HTTP/3를 사용할 수 있을까?

Web Browser

현재 Chrome, Edge, Firefox는 http/3을 지원하고 있습니다.

Server

현재 QUIC을 구현하고 있는 구현체는 다음 위키에서 확인하실 수 있습니다. QUIC

대표적인 웹서버인 NGINX NGINX QUIC Preview

그리고 Webflux에서 사용되는 자바의 Netty netty/netty-incubator-codec-quic

의 경우 아직 개발 단계 중인 것을 확인할 수 있습니다.

실제로 어플리케이션 단계에서 이용하려면 아직까지는 시간이 조금 더 필요할 것 같습니다.

Public Cloud

AWS는 아직까지는 QUIC을 지원하지 않고 있습니다.

GCP의 경우 당연히 구글이 QUIC을 개발한 만큼, CDN과 로드밸런서에서 제공 중입니다.

Cloud CDN and Load Balancing support HTTP/3 | Google Cloud Blog

이외에도 Cloudflare 같은 CDN을 제공하는 업체에서도 이미 http/3 기능을 제공중입니다

 

 

참고 링크