HTTP 버전별 총 정리

date
Dec 22, 2023
slug
http-version-summary
summary
‘HTTP 완벽 가이드’를 읽고 http 버전들을 정리해보자
thumbnail
status
publish
최근 HTTP 완벽 가이드 서적으로 스터디를 진행중에 있다. 오랜만에 HTTP 관련 이론적인 지식을 다룰수 있는 기회가 된 것 같아서 버전별 특징을 정리해본다. 🤓

HTTP

Hypertext Transfer Protocol
호스트간 통신하는데, 몇가지 규칙을 특징으로 갖고있는 기초적인 통신 프로토콜 웹 브라우저, 서버, 웹 애플리케이션 모두 HTTP를 통해서 서로 대화한다. HTTP는 현대 인터넷의 공용어이다.
  • 클라이언트-서버 구조 클라이언트가 요청을 보내고 서버가 응답하는 클라이언트-서버 구조
  • 무상태성 (Stateless) 서버나 클라이언트의 상태를 기억하고 있지 않기 때문에 각각의 요청을 독립적으로 여기고 특정 클라이언트의 요청을 알아채지 못한다. 따라서 쿠키세션를 이용하여 추가적인 정보를 교환하며 클라이언트를 판단한다.
  • 비연결성 (Connectionless) 리소스를 공유하고 연결을 바로 끊어 서버 부하를 줄인다. 하지만, 매 통신마다 연결을 다시 하면 TCP 특성상 TCP 연결(3-Way Handshaking) 비용이 지속적으로 발생할 수 있다.
    • 💡
      3-Way Handshake
      notion image
      TCP가 호스트 간에 연결을 설정하는 방법으로 SYN/ACK 패킷을 통해 이루어진다. SYN 패킷은 동기화(SYNchronize)를 의미하는 패킷이며 ACK 패킷은 확인(ACKnowledgement)을 의미하는 패킷이다. 클라이언트-서버간 3번의 통신으로 연결을 확정짓는다.

HTTP/0.9

원래 HTTP 초기 버전에는 버전 번호가 없었다! 이후 버전들이 나오면서 0.9 라고 지칭되었다.
단일 라인 요청으로 리소스에 대한 메소드는 Get만 존재했다. 헤더조차 존재하지 않았기 때문에 HTML 문서만 전송이 가능했다. 상태 코드 및 오류 코드도 존재하지 않았다.

HTTP/1.0

헤더가 요청과 응답 둘 다 도입되어, 메타데이터 전송이 가능해졌다. Content-Type 헤더로 인해서 HTML 문서외 다른 리소스들의 통신이 가능해졌다.
상태 코드가 응답의 시작에 붙어 클라이언트가 요청에 대한 성공과 실패 여부를 알 수 있게 되었다.

단기 커넥션 (Short lived Connections)

새로운 커넥션 마다 TCP 연결(3-Way Handshaking)이 필요하기 때문에 성능이 저하된다. 이는 HTTP/1.1 - 지속 커넥션 (Persistent Connection)에서 개선된다.

HTTP/1.1

notion image

병렬 커넥션 (Parallel Connection)

대역폭을 쪼개서 여러 개 커넥션을 연결한다. 이를 이용해 다수의 요청을 병렬로 처리할 수 있게된다.
일반적으로 병렬 커넥션은 빠르지만 클라이언트의 대역폭이 좁거나 다수의 커넥션 처리를 위해 서버에 부하가 생겨 느려질 수도 있다.
여러 개의 커넥션을 위해 TCP 연결(3-Way Handshaking)을 여러번 해야하는 입장인 것이다.

지속 커넥션 (Persistent Connection)

HTTP/1.1 부터는 기본적으로 지속 커넥션이 작동한다.
한번에 커넥션으로 여러 개의 트랜잭션을 가능하게 한다. 새로운 TCP 연결(3-Way Handshaking)를 하는 비용을 아끼고, TCP의 혼잡 제어를 활용할 수 있다.
💡
TCP의 혼잡 제어 방식에서 Slow Start는 커넥션을 열어둘수록 전송가능한 패킷이 2배씩 들어나므로, 커넥션 연결이 지속될수록 효과적이다.
💡
HTTP/1.0+에서는 Keep-Alive 헤더를 통해 지속 커넥션을 조절한다. 하위 프로토콜에 대한 호환을 위해 적기도 한다.

파이프라이닝 (Pipelining)

지속 커넥션을 이용해서 응답을 기다리지 않고 곧바로 다른 트랜잭션들을 요청해 여러개의 요청을 병렬로 처리가능하게 한다. GETHEADPUT 그리고 DELETE 메서드같이 멱등한(idempotent) 메서드만 가능하다.

한계

  • HOL(Head Of Line) Blocking
파이프라이닝(Pipelining)은 우선순위가 없어서 요청들을 순서(FIFO)에 맞춰서 응답을 해야한다. 만약 첫번째 요청의 처리속도가 늦어지면 후속 요청들은 처리가 빨리 끝나도 대기해야하는 병목 현상이 나타난다.
이를 HOL(Head Of Line) Blocking으로 지칭한다. 따라서 파이프라이닝(Pipelining)은 모던 브라우저에서 기본적으로 활성화되어있지 않다.
  • RTT(Round Trip Time) 증가
RTT(Round Trip Time)란, 클라이언트-서버간 요청에 대한 응답 왕복 시간(패킷 왕복 시간)을 의미한다.
매번 요청 별로 Connection을 만들게 되는 HTTP의 특성상 3-way handshake가 반복적으로 일어나며, 불필요한 RTT 증가와 네트워크 지연을 초래하여 성능을 악화시킨다.

HTTP/2.0

HTTP/1.1의 한계를 느낀 구글이 차세대 프로토콜 개발 SPDY(스피디)를 개발하여 긍정적인 효과를 보자 HTTP Working GroupSPDY를 기반으로 고도화하여 HTTP/2.0 탄생시켰다.

Binary Framing Layer

notion image
HTTP/2.0HTTP1.1의 큰 차이점은 HTTP 메세지를 plain text에서 binary frame으로 인코딩한다는 점이다. 이는 성능 향상에 큰 장점을 가져다줬다.
💡
프레임 (Frame)HTTP/2.0에서 통신의 최소 단위이며 각 단위에는 프레임 헤더가 포함된다. Header 혹은 Data가 들어있다.

Header 압축

notion image
헤더를 전달하는 과정에서 허프만 코딩 압축 방식을 기반으로하는 HPACK 압축 방식이 사용된다. 헤더의 크기를 줄이고 중복되는 헤더는 재전송하지 않는다.

스트림 (Stream)

notion image
커넥션을 통해 호스트 사이에서 교환되는 프레임들의 독립된 양방향 시퀸스이다. 한쌍의 HTTP 요청과 응답은 하나의 스트림을 통해서 이루어진다.
여기서 중요한건 하나의 커넥션에 여러 스트림이 열릴수 있다는 것이다. 이를 통해 요청을 병렬적으로 처리할 수 있게 되었고 멀티플렉싱(multiplexing)이라고 한다.
💡
우선 순위부여
HTTP/1.1과 다르게 스트림은 우선 순위를 가질 수 있다. 중요한 리소스를 요청하는 스트림에게 우선순위를 높게 부여하는 것이다. 이는 HOL(Head Of Line) Blocking 문제를 해결했다.

서버 푸시

HTTP/2.0에서 서버는 원래 요청에 대한 응답 외에도 클라이언트가 필요한 리소스를 명시적으로 요청하지 않고도 미리 캐싱해두어 필요한 리소스 요청이 올 때 빠르게 클라이언트에 보낼 수 있다.

HTTP/3.0

TCP의 한계

HTTP는 TCP 기반 위에서 동작되기 때문에, TCP 연결(3-Way Handshaking)에서 발생하는 지연 시간이 발생한다.
TCP 신뢰성 의 특징으로 패킷이 유실되거나 오류가 발생할 때, 패킷 재전송 과정을 거치게 된다. 이때 패킷 지연이 발생하면 HOL(Head Of Line) Blocking 문제가 발생되었다. 즉, TCP/IP 4 계층애플리케이션 계층(L4)에서 HTTP의 HOLB를 해결했지만, 전송 계층(L3)에서의 TCP의 HOLB를 해결한건 아니다.

QUIC의 도입

결국 TCP가 문제다…!
이를 위해 HTTP/3.0에서는 UDP 기반의 프로토콜인 QUIC(Quick UDP Internet Connections를 도입했다.