http란
HTTP(HyperText Transfer Protocol)
웹에서 정보를 주고 받을 수 있는 프로토콜이다
http/1.0 이전엔 Method는 GET이 유일했으며, Header 또한 존재하지 않아 오직 HTML 파일만 전송이 가능했다
그로인하여 상태확인 코드 또한 존재하지 않았다.
이런 제한적인 기능을 개선하여 http/1.0에선 다음과 같은 기능들이 추가되었다.
HTTP의 첫 번째 표준버전으로 발표되었고 이전 버전보다 많은 개선사항이 도입되었다.
- Connection Keep-Alive
- 파이프라이닝 추가/ 이전 요청에 대한 응답이 완전히 전송되기 전 다음 전송을 가능하게 하여 처리량을 늘림
- 청크된 응답 지원
- 캐시 제어 메커니즘
- 언어, 인코딩 타입 등을 포함한 컨텐츠 전송
- 동일 IP 주소에 다른 도메인을 호스트하는 기능 추가 (HOST header)
1.1에서의 큰 개선점이라고 하면
기존 TCP 연결 기반 위에서 동작하는 프로토콜로 신뢰성 확보를 위해 연결을 맺고 끊는 Handshake를 개선한것 이다, 한번의 요청과 응답이 끝나면 연결이 끊어졌고 그때마다 Handshake를 하기에 비연결성 프로토콜에선 Overhead가 생겼다.
Keep-Alive 기능이 추가되어 한번 맺어졌던 연결을 끊지않고 지속적으로 유지하여 불필요한 Handshake를 줄여 성능을 효율적으로 개선했다.
HTTP HOLB
파이프라이닝의 기술은 하나의 커넥션에서 한 번에 순차적인 여러 요청을 연속적으로 요청하고 받아야 하다보니 먼저 받은 요청이 끝나지 않으면 뒤에 요청이 아무리 빨리 처리가 되었더라도, 먼저 온 요청이 처리기 끝날때까지 대기해야하는 HOL(Head Of Line) Blocking
문제가 발생했다.
RTT(Round Trip Time)
TCP상에서 동작하는 http의 특성상 Handshake가 반복적으로 일어나 불필요한 RTT 증가와 네트워크 지연을 초래하여 성능을 저하 시키게 되었다.
무거운 Header 구조
헤더에는 많은 메타정보들이 저장되어 전달되었고 사용자가 방문한 웹페이지는 다수의 http 요청이 일어나게 되는데, 이 경우 매 요청시 마다 중복된 헤더값을 전송하게 되며 또한 해당 도메인에 설정된 쿠키 정보까지 헤더에 포함되어 전송되니 전송값보다 헤더가 큰 경우가 생겼다.
http/2는 완전히 새로운 프로토콜이 아닌 구글 SPDY의 개선사항을 적용하여 성능향상에 초점을 맞춘 프로토콜으로 설명이 가능하다
- Multiplexed Streams
한 커넥션으로 동시에 여러 개의 메세지를 주고 받을수 있으며, 응답의 순서에 상관없이 Stream으로 주고 받는다.
1.1에서 Keep-Alive와 파이프라이닝의 성능저하적인 문제를 개선했다.
- Stream Prioritization
HTML 문서안 파일들 중에 Image파일보다 CSS파일의 수신이 늦어져 브라우저의 렌더링이 늦어지는 문제가 발생하는데 HTTP/2 에선 리소스간의 우선순위를 설정하여 이런 문제를 해결했다
- Server Push
서버는 클라이언트의 요청에 대해 요청하지 않은 리소스를 보내줄 수 있게 되었다.
기존 1.1에선 클라이언트가 요청한 HTML문서를 수신한 뒤 HTML문서를 해석하며 필요한 리소스를 재요청 하였지만, HTTP/2에서 Server push 기법을 통해 클라이언트가 요청하지 않은 리소스를 Push하여 클라이언트의 요청을 최소화 시켜 성능 향상을 이끌어냈다.
- Header Compression
Header 정보를 압추하기 위해 HPACK 압축방식을 도입했다
Header에 중복값이 존재하는 경우 Static/Dynamic Header Table 개념을 사용해 중복 Header를 검출하고 중복된 Header의 index값만 전송하고 중복되지 않은 헤더 정보의 값은 Huffman Encoding 기법으로 인코딩 처리해 전송했다.
여전히 TCP를 이용하고 있기 때문에 Handshake의 RTT로 인한 지연시간 및 TCP의 HOLB 문제를 완벽히 해결할 수 없다.
기존 TCP 기반의 http/1.1 && http/2 와는 다르게 http/3는 UDP
기반 프로토콜인 QUIC
를 사용해 통신하는 프로토콜이다.
- RTT 감소로인한 지연시간 단축
클라이언트가 보낸 요청을 서버가 처리한 후 다시 클라이언트에게 응답해주는 사이클을 RTT라 했는데, TCP는 기본적으로 1RTT가 필요하며, TLS를 사용한 암호화까지 한다면 TLS의 자체 핸드쉐이크까지 총 3RTT가 필요했다.
QUIC는 TCP를 사용하지 않기 때문에 통신을 시작할 때 번거로운 3 Way Handshake 과정을 생략했다.
첫 연결 설정에 1RTT만 필요로하며, 이유는 연결 설정에 필요한 정보와 데이터를 함께 보내기 때문이다 그로인해 클라이언트가 서버에 어떤 신호 한번을 주고, 서버도 거기에 응답하기만 하면 바로 본 통신을 시작할 수 있다는 것이다.
- 패킷 손실 감지에 걸리는 시간 단축
QUIC는 패킷마다 고유한 패킷 번호를 부여해 패킷의 고유 번호를 가지고 있어 패킷 손실 감지에 걸리는 시간을 단축할 수 있게 하였다.
- 멀티플렉싱 지원
http/2와 같은 멀티플렉싱을 지원하고 있다.
QUIC 또한 동일하게 지원하기 때문에, 이런 이점을 그대로 가지고 있으며 하나의 스트림에 문제가 발생하더라도 다른 스트림은 지킬 수 있게 되어 이러한 문제에서 자유롭다
- 클라이언트의 IP가 바뀌어도 연결 유지
TCP의 경우 소스의 IP주소와 포트, 연결 대상의 IP 주소와 포트의 연결을 식별하기 때문에 클라이언트가 IP주소가 바뀌는 상황이 발생하면 연결이 끊어지게 된다,
연결이 귾어졌으니 다시 연결을 위한 핸드쉐이크 과정을 거쳐야하는 것이고 여기서 다시 레이턴시가 발생한다 특히 모바일의 경우 Wi-fi, 셀룰러 전환으로 인한 IP 변경이 잦다.
반면 QUIC는 커넥션 ID를 사용해 서버와 연결을 생성한다, 커넥션 ID는 랜덤한 값일뿐 클라이언트의 IP와 무관한 데이터이기에 클라이언트의 IP주소가 변경되더라도 기존의 연결을 계속 유지할 수 있어 핸드쉐이크 과정을 생략할 수 있다.
1.1은 이전 버전에서 한정적인 Http 프로토콜의 기능과 Connection Keep-Alive 와 파이프라이닝으로 불필요한 핸드쉐이크 과정을 줄여 이전 버전들보다 성능 향상을 이루어 냈다
2는 1.1의 성능 저하의 문제가 되었던 부분을 개선해낸 버전이라고 설명할 수 있다.
멀티플레싱, 서버 푸쉬 기법과 리소스에 우선순위를 정해주고 무거운 헤더를 해결한 버전이다
큰 핵심은 2는 스트림 하나가 다수개의 요청과 응답을 처리하는 구조로 바뀐것이다.
그리고 1.1과 2는 TCP를 기반으로 동작하고 있다
http3는 1.1과 2와 다르게 TCP가 아닌 QUIC를 사용해 새롭고 효율적이게 개선한 프로토콜이라고 할 수 있다.
물론 http2의 멀티플렉싱 기능 같은 좋은 기능을 가져오고, 이전 버전에서 고질병이던 핸드쉐이크 문제를 QUIC를 통해 더 효과적으로 성능을 개선해냈다.
참고