프로그래밍/Network

간단하게 살펴보는 HTTP의 진화과정

Lou Park 2023. 9. 17. 10:40

HTTP/1.0

handshake

HTTP/1.0에서는 클라이언트/서버간 각 요청/응답에 대해 새로운 TCP 연결을 생성한다.

그래서 각 요청전에 TCP 및 TLS 핸드셰이크가 완료되어야 했고, 모든 요청에 대기시간 패널티가 발생했다

 

HTTP/1.1

한번의 TCP 연결을 유지하고자 Keep-alive가 등장했다.

하지만 HTTP/1.1에서는 클라이언트가 한 번에 하나의 HTTP 요청/응답 교환만 허용했으므로

네트워크 계층에서 동시성을 얻는 유일한 방법은 TCP 연결을 병렬로 사용하는 것인데, Pipelining을 통해 여러 요청을 전송했을때, 첫번째 요청에 대한 응답이 지연되면 뒤에 따라오는 모든 응답도 같이 지연되었는데 이를 “Head of line Blocking”이라고 한다. 이는 RFC 2616에서 서버는 반드시 요청순서에 맞추어 응답을 전달해야한다는 규칙에 의한다.

 

HTTP/2

h1 vs h2

HTTP “Stream” 개념이 도입되었다.

여러 요청/응답을 한 번의 TCP 연결을 통해 동시에 전송할 수 있기 때문에 TCP 연결을 효율적으로 사용가능했다.

하지만 패킷이 손실될 경우 문제가 발생한다.

TCP는 하나의 Endpoint에서 다른 Endpoint로 전체 바이트 스트림을 올바른 순서로 전달하는 역할을 하는데,

해당 바이트중 일부가 손실되면 TCP는 손실된 패킷을 다시 보내 스트림의 공백을 채우게된다.

 

독립된 요청이라고 해도 그저 전송 레이어에서는 바이트 스트림에 불과하기 때문에 여러 요청중에 손실된 바이트 뒤에 오는 요청이 성공했다고 하더라도 애플리케이션에 전달될 수 없어 불필요한 지연이 일어나게 된다.

HOL(Head of line) Blocking 문제가 TCP 레벨에서 나타나게 된다.

 

HTTP/3

출처: https://www.youtube.com/watch?v=BazWPeUGS8M

새로운 인터넷 전송 프로토콜인 QUIC을 사용한다.

QUIC 스트림은 동일한 QUIC 연결을 공유하므로 새 스트림을 생성하기 위한 추가 핸드셰이크가 필요하지 않다.

또한 한 스트림에 발생한 패킷 손실이 다른 스트림에 영향을 미치지 않도록 독립적으로 전달된다. 이는 QUIC 패킷이 UDP 데이터그램 위에 캡슐화 되어있기 때문에 가능하다.