목차
서론
최근 구글이 새로운 프로토콜을 만들었습니다 그리고 구글은 이를 적극적으로 활용하고 있습니다.
사진을 보면 구글을 들어갔을 때 빨간색으로 표시한 것처럼 프로토콜이 h3
라고 표시되어 있습니다.
이는 HTTP/3의 약자이며 HTTP/3라고 불리는 QUIC을 한 번 알아봅시다.
배경지식
TCP
우리가 사용하는 인터넷은 전송할 때 중간에 정보가 사라져도 이상하지 않습니다. 하지만 우리는 정확한 데이터를 전송해야 할 필요성이 있습니다. 그래서 만들어진 것이 TCP입니다. 위키백과에서 TCP를 다음과 같이 설명하고 있습니다.
전송 제어 프로토콜(Transmission Control Protocol, TCP, 전송조종규약)은 인터넷 프로토콜 스위트(IP)의 핵심 프로토콜 중 하나로, IP와 함께 TCP/IP라는 명칭으로도 널리 불린다.
인터넷의 대부분이 TCP로 이루어져 있는만큼 중요한 프로토콜입니다.
TCP의 구조
연결은 연결을 받아드리는 곳(서버)와 연결을 시도하는 곳(클라이언트) 사이에서 이루어집니다. 처음에는 서로 연결이 잘 되었는지 몇 가지 정보를 보내 확인합니다. 서버와 클라이언트 사이에서 총 3번 왔다갔다 하므로 3-way handshake라고 합니다. (이 글에서는 대략적인 것만 살펴볼 것으로 자세한 내용은 직접 찾아보세요)
그 뒤, 매번 내용을 전송할 때, 일정 크기인 패킷에 담아서 전송하게 되는데, 패킷이 도착했으면 상대방이 패킷의 내용이 맞는지 체크섬을 확인하고 받았다는 신호를 전송합니다. 내용이 맞지 않거나 도착하지 않았으면 받았다는 신호를 전송하지 못하게 됩니다. 패킷을 보낸 뒤 일정 시간이 지나도 받았다는 신호를 받지 못하면(타임아웃) 다시 패킷을 전송하게 됩니다.
위와 같은 방법으로 패킷을 순서대로 보내게 됩니다. 패킷의 순서가 뒤바뀌면 내용이 달라지므로 무조건 앞 패킷이 도착한 것을 확인한 후에 다음 패킷을 전송하게 되는데, 패킷이 손실되면 다음 패킷을 보내는 것을 막기 때문에 조그만한 손실률 차이가 큰 차이를 만들어 냅니다.
데이터를 모두 주고 받은 뒤에는 4-way handshake를 통해 연결이 종료됩니다.
TCP의 특징
TCP는 handshake를 하기 때문에 처음 연결할 때 느립니다. 더욱이 흔히 HTTPS로 알고 있는 것은 HTTP를 TCP+TLS 위에서 주고 받는 것인데, TLS도 연결할 때 handshake를 하기 때문에 더욱 오래 걸립니다. TCP+TLS는 총 3-RTT(Rount Trip Time, 왕복 횟수)가 걸립니다.(TLS 1.3 기준)
또한 TCP 패킷의 헤더는 32바이트로 헤더 크기의 크기도 큰 편입니다. 정리하자면 TCP는 데이터를 안전하게 보내는 것만이 목적인 프로토콜입니다.
UDP
TCP와 같이 항상 나오는 프로토콜인 UDP가 있습니다. 위키백과에서는 UDP를 다음과 같이 설명하고 있습니다.
사용자 데이터그램 프로토콜(User Datagram Protocol, UDP)은 인터넷 프로토콜 스위트의 주요 프로토콜 가운데 하나이다. TCP와 함께 데이터그램으로 알려진 단문 메시지를 교환하기 위해서 사용된다.
UDP의 구조
UDP의 구조는 매우 단순합니다. 원하는 IP로 그냥 데이터를 보내면 됩니다. 헤더에 체크섬이 포함되어 있어서 받는 사람은 이 데이터가 잘못되었는지 알 수 있지만, 데이터가 잘못되어도 UDP상에서는 데이터를 다시 받을 방법이 없습니다.
UDP의 특징
UDP는 TCP와 다르게 handshake를 하지 않습니다. 그래서 연결이라는 개념이 없고 비연결성 통신이라고 합니다.
또한 UDP의 패킷의 헤더의 크기는 송신자의 IP, 수신자의 IP, 데이터의 길이, 데이터의 체크섬만이 들어가 8바이트로 매우 짧습니다.
OSI 7계층
OSI 7계층은 인터넷을 7개의 계층으로 나눠놓은 것으로 위키백과에서는 다음과 같이 설명하고 있습니다.
OSI 모형(Open Systems Interconnection Reference Model)은 국제표준화기구(ISO)에서 개발한 모델로, 컴퓨터 네트워크 프로토콜 디자인과 통신을 계층으로 나누어 설명한 것이다.
앞서 설명한 TCP와 UDP는 4계층에 속하며, HTTP는 7계층에 속합니다.
SSL/TLS
OSI 5계층에 속하며 보안 연결을 할 수 있게끔 해주는 프로토콜입니다. 위키백과에서는 다음과 같이 설명하고 있습니다.
전송 계층 보안(영어: Transport Layer Security, TLS, 과거 명칭: 보안 소켓 레이어/Secure Sockets Layer, SSL)는 컴퓨터 네트워크에 통신 보안을 제공하기 위해 설계된 암호 규약이다.
HTTP의 역사
HTTP/1.1
HTTP/1.1은 HTTP의 버전 1.1입니다. 처음으로 공개적으로 공개된 버전으로 매우 단순하게 이루어져 있습니다.
Request
GET /hello.htm HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
Host: www.tutorialspoint.com
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Response
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache/2.2.14 (Win32)
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
Content-Length: 88
Content-Type: text/html
Connection: Closed
<html>
<body>
<h1>Hello, World!</h1>
</body>
</html>
위처럼 공백 및 줄바꿈을 통해 첫 줄과 헤더, 본문을 구분합니다. 매우 단순하고 파싱하기 간편하지만 헤더가 반복되거나 압축이 되면 전송속도가 빨라질 가능성이 보입니다.
HTTP/2
이러한 점을 개선한 것이 HTTP/2입니다.
먼저 반복되는 헤더를 위한 HPACK 알고리즘을 이용해 압축을 하였습니다. 헤더에는 웹사이트의 쿠키 등 매우 긴 내용도 들어갈 수 있기 때문에 헤더의 크기를 줄이는 것이 중요합니다.
또한 일반적으로 웹사이트에 방문하게 되면 HTML을 브라우저가 읽고 다른 스크립트 파일이나 이미지 등을 요청하게 됩니다. 기존의 HTTP/1.1에서는 각 요청마다 TCP 연결을 만들어서 요청했지만 HTTP/2에서는 이를 하나의 TCP 연결에서 multiplexing이라는 기술을 활용하여 사용하였습니다. 이를 통해 많은 handshake의 과정을 간소화할 수 있게 되었습니다.
HTTP/2 with push
여기서 또 한 번 생각해보면 웹사이트마다 다시 요청하는 파일들은 같을 것입니다. 그래서 미리 요청할 파일들을 같이 보내주는 과정을 만들었습니다. 이를 통해 요청을 하는 과정도 줄일 수 있게 되었습니다.
다음은 앞서 배운 세 가지 방법을 나타낸 것입니다. (출처)
구글의 야심작 QUIC
기존 프로토콜의 단점
HTTP/2가 HTTP/1.1의 단점을 보완하였지만 그래도 많은 단점이 남아있었습니다.
먼저 HOL(Head of Line) Blocking이 발생한다는 점입니다. HOL Blocking이란 앞선 데이터가 전송에 실패하였을 때, 뒤의 데이터가 앞의 데이터가 다시 보내지는 것을 기다리게 되는 것을 말합니다. 앞서 TCP에서는 그러한 현상이 발생한다고 했었죠.
결국 HTTP/2는 TCP의 고질적인 문제로 인해 성능이 나빠지게 된 것입니다. 그렇기 때문에 HTTP/2는 하나의 TCP 연결을 사용하기 때문에 다수의 TCP 연결을 사용하는 HTTP/1.1보다 HOL Blocking으로 인해 성능이 나빠질 수 있습니다. 손실률 2%의 네트워크에서는 HTTP/2보다 HTTP/1.1의 성능이 더 낫다고 합니다. (출처)
그래서 HTTP/2를 UDP위에서 작동시켜 보자고 한 것이 QUIC 프로토콜의 시작입니다.
QUIC이란
앞서 QUIC은 UDP를 사용한다고 하였는데, UDP는 아무런 기능이 없기 때문에 오히려 QUIC을 구현할 때에는 이득이 되었습니다. UDP는 그저 전송을 하는 프로토콜이기 때문에 실제로 UDP위에서 체크섬을 확인하고 맞지 않으면 다시 보내는 로직을 구현하면 TCP와 비슷해지게 됩니다.
QUIC은 UDP위에서 논리적 스트림을 사용하여 HOL Blocking을 막았습니다. 기존의 HTTP/2에서는 여러 논리적 스트림을 사용해도 하나의 스트림에서 막히면 다른 스트림의 패킷도 전달이 되지 않았는데, UDP위에서 구현하게 되면서 막힌 스트림만 개별적으로 처리할 수 있게 된 것입니다. 그러면서 각 스트림에서는 순서가 보장됩니다.
다음은 스트림에서 순서가 보장된다는 것을 표현한 것입니다. (출처)
기존의 HTTP/2
QUIC
UDP를 사용하면서 연결에 사용되는 정보가 IP와 포트 밖에 없기 때문에 자체적인 connection ID를 만들어서 통신을 하게 됩니다. 이렇게 QUIC은 TCP의 단점인 HOL Blocking을 해결하면서 기존의 기능들을 빼놓지 않았습니다.
또한 QUIC에 다른 기능도 추가되었습니다. 인터넷 상에서는 보안 연결을 위해 TLS가 필수인데, 이를 QUIC과 병합하였습니다. (TLS 1.3) 즉, QUIC을 사용하기 위해서는 무조건 TLS를 사용해야 합니다. 또한 이렇게 병합하므로써 handshake를 병합하여 기존의 HTTP/2 + TLS가 3-RTT에서 1-RTT까지 줄일 수 있게 되었습니다.
이론상 1-RTT가 최소이므로 최소한으로 handshake를 줄인 셈입니다. 심지어 한 번 연결한 적 있으면 기존의 정보를 활용해 0-RTT까지 줄일 수 있습니다.
다음은 이를 간단하게 표현한 그림입니다. (출처)
이러한 QUIC 프로토콜 위에서 HTTP를 사용하는 것이 HTTP over QUIC, HTTP/3이라고 합니다. (IETF draft) QUIC 위에서 HTTP를 사용하므로 헤더 압축 알고리즘도 HPACK이 아닌 QPACK을 사용합니다.
QUIC의 단점
그렇다면 기존의 HTTP/2의 단점을 모두 해결하였는데, QUIC는 단점이 없을까요? QUIC도 몇 가지의 단점이 있습니다. 먼저 최근에 나온 프로토콜이라는 점이 가장 큰 단점입니다. TCP는 OS에서 구현을 하기 때문에 커널과의 최적화가 잘 되어 있고 오랜 기간 개발이 되어 왔기 때문에 코드 자체의 최적화도 잘 되어 있습니다. 반면 TCP의 업데이트는 OS 업데이트를 통해야지만 가능합니다. 또한 UDP는 잘 사용되어오지 않았기 때문에 OS에서 최적화가 많이 되어 있지 않습니다. 이러한 점이 QUIC에게는 불리하게 작용합니다.
QUIC은 유저 코드로 작성되기 때문에 UDP의 최적화 문제 이외에도 QUIC 코드의 최적화도 덜 되어 있습니다. 하지만 이점이 후에는 업데이트가 용이하다는 장점이 될 수는 있습니다. 아직 QUIC 코드의 최적화가 덜 되어있기 때문에 전력을 최대 2배 더 사용한다는 이야기가 있지만 이는 곧 개선될 것으로 보입니다.
QUIC 프로토콜 자체의 단점도 있습니다. QUIC으로 요청을 보내게 되면 한 번의 handshake에 많은 내용이 들어가기 때문에 요청 패킷의 길이가 짧더라도 응답의 패킷의 길이가 길게 됩니다. 그러면 이러한 증폭을 이용하면 적은 양의 요청으로 디도스 공격을 쉽게 가능하게 합니다. 이를 방지하고자 초기 패킷의 길이가 1200바이트를 넘지 않아야 한다는 조건과 요청 길이의 3배를 넘기지 말아야 한다는 조건을 새로 추가하였습니다.
추가적인 내용
사실 구글에서 만든 QUIC은 TLS가 아닌 더 효과적인 암호화 방식을 사용하려고 했습니다. 하지만 IETF에서 TLS 1.3을 사용하는 것으로 정하면서 Google-QUIC와 HTTP/3는 다른 개념으로 바뀌게 되었습니다. 이외에도 다른 부분이 몇 가지 있지만 Google 버전의 QUIC와 IETF 버전의 QUIC이 다르다는 것을 알고 계시는 것이 중요합니다.
정리
TCP | UDP | QUIC | |
---|---|---|---|
연결 지향성 | O | X | O |
순서 보장 | O | X | 각 스트림에서만 O |
HOL Blocking | O | X | 각 스트림에서만 O |
데이터 전송 보장 | O | X | O |
헤더 크기 (바이트) | 32 | 8 | 20 or 12 |
handshake | O | X | O |
다음은 함께 보면 좋을 문서들입니다.