본문 바로가기
IT 개인 공부/Web

HTTP 프로토콜 발전

by Libi 2021. 9. 2.
반응형

대부분의 인터넷은 HTTP 프로토콜을 기반으로 통신한다.

HTTP 프로토콜은 Hypertext Transfer Protocol의 약자로 TCP/IP 위에서 작동하는 인터넷상에서 데이터를 주고받기 위한 서버/클라이언트 모델을 따르는 프로토콜이다.

 

HTTP는 1965년부터 등장하여 부족한 성능을 개선해나가면서 현재 HTTP 3.0 버전까지 등장하였다.

Naver, Google 등 다양한 웹사이트를 접속하면 여러 버전의 HTTP를 사용 중인 것을 확인할 수 있다.

 

HTTP는 TCP/IP 계층의 Application 계층에서 동작한다. 또한 Application 계층의 프로토콜들은 추가적인 기능을 제공하기 위해 Transport 계층의 TCP or UDP 프로토콜을 활용한다.

기본적으로 HTTP는 연결 지향적이고 신뢰성 있는 데이터를 제공하기 위해 TCP 프로토콜 위에서 동작한다. 하지만 이러한 특성들을 제공하기 위해서 어쩔 수 없이 성능이 저하되는 단점이 발생하게 된다.

HTTP 발전 과정은 이러한 성능상의 단점들을 개선하기 위해서 이루어졌다고 생각하면 쉽다.

그렇다면 HTTP 발전 과정에 대해서 한번 알아보도록 하자.

 

 

HTTP 0.9

 

  • GET 메서드만 지원하는 초기 HTTP 프로토콜
  • Header를 가지지 않기 때문에 HyperText 이외에 다른 데이터는 전송할 수 없음
  • 응답 직후 종료
  • 원라인 프로토콜이라고 부름

 

초기 HTTP 프로토콜은 굉장히 단순하다. 하지만 GET 방식과 HyperText만 전송하는 기능을 제외한 별다른 기능이 없다는 단점이 있다.

이를 개선하기 위해 확장시킨 것이 바로 HTTP 1.0이다.

 

 

HTTP 1.0

 

  • GET, HEAD, POST 메서드 지원
  • Header라는 개념이 등장
  • Header에 상태 코드, 데이터 타입, 캐시 관련 헤더 등을 추가함으로써 다양한 기능을 제공

 

HTTP 1.0은 Header라는 개념을 도입하면서 다양한 기능을 제공할 수 있게 되었다. 하지만 요청마다 새로운 커넥션을 생성하여 연결하고 끝나면 끊어야 하는 단점이 존재한다.

그렇다면 매 요청마다 새로운 커넥션을 생성하지 말고 재사용할 수 있다면 해결할 수 있지 않을까?

이를 위해 Keep-alive라는 기능이 탄생하게 된다.

 

 

HTTP 1.1

 

  • Persistent Connection : 지정한 timeout 동안 커넥션을 한 번만 사용한 후 끊는 것이 아니라 재사용함
  • Keep-alive 기능
  • 또한, HTTP는 클라이언트의 순차적으로 요청을 받아서 처리 후 응답하는 방식
  • 먼저 온 요청을 처리하는 시간이 많이 소요된다면 다른 클라이언트는 요청이 전송되기까지의 대기 시간이 발생
  • Pipelining 도입
  • 하나의 커넥션에서 응답을 기다리지 않고 순차적인 여러 요청을 연속적으로 보내 그 순서에 맞춰 응답을 받는 방식

 

Persistent Connection을 통해 커넥션을 재사용하며 Pipelining을 통해 클라이언트의 요청 전송 대기 시간도 줄일 수 있게 되었다.

하지만 HTTP 1.1 역시 다음과 같은 문제점들이 존재한다.

 

Head Of Line Blocking

클라이언트의 요청 전송 대기 시간은 줄였지만 HTTP는 요청을 순차적으로 응답해줘야 하기 때문에 앞의 요청을 처리하는 시간이 오래 걸리면 뒤의 요청이 처리가 끝나더라도 응답을 보낼 수 없음

Header 구조의 중복

연속된 요청들은 한 클라이언트가 보내는 요청이기 때문에 Header가 중복되는 부분이 많이 존재한다. 하지만 이를 매 요청마다 추가해서 보내야 하기 때문에 성능 저하가 발생하게 된다.

 

이러한 문제점들 개선하기 위해 HTTP 2.0이 등장하게 된다.

 

 

HTTP 2.0

 

  • HTTP 메시지 전송 방식의 변화 : Binary Framing 계층 사용
  • 기존 Plane 텍스트가 아닌 Binary 프레임으로 인코딩
  • 파싱, 전송 속도 향상 및 오류 발생 가능성 낮아짐

  • 이렇게 구성한 프레임들을 합친 것이 요청 및 응답 메시지
  • 이러한 프레임은 Streams라는 통로를 통해 전송됨
  • Streams : 구성된 연결 내에서 전달되는 바이트의 양방향 흐름, 하나 이상의 메시지가 전달 가능함
  • 메시지가 프레임으로 쪼개졌기 때문에 메시지 간의 순서가 사라졌으며, 프레임은 중간에 끼어들 수 있는 특성을 가지기 때문에 Head Of Line Blocking 문제를 해결 가능
  • Stream Prioritization : 리소스 간의 우선순위를 설정하여 랜더링이 늦어질 때 발생할 수 있는 문제를 해결
  • Stream마다 우선순위 가중치를 매길 수 있기 때문에 중요한 데이터의 스트림을 먼저 전송할 수 있음
  • Server Push : 클라이언트가 요청하지 않아도 서버 측에서 나중에 필요할 것 같다고 생각되는 리소스를 미리 전송
  • Header Compression : 중복되는 Header를 Header Table과 Huffman Encoding 기법을 활용하여 압축
  • 헤더 크기를 약 80% 줄이는 성과를 얻었으며 덕분에 페이지 로드 시간이 감소함

 

HTTP 2.0은 다양한 방식들을 도입함으로써 HTTP 1.1의 단점들을 개선하였다. 하지만 HTTP는 결국 TCP 위에서 동작하기 때문에 TCP Head Of Line Blocking, 3-Way Handshake 방식으로 인한 성능 저하를 피할 수 없다.

HTTP 2.0은 다수의 요청을 한 개의 Streams에서 병렬적으로 처리하기 때문에 하나의 Stream에서 문제가 발생하면 관련 없는 Stream들도 대기해야 하는 문제가 발생한다.

하지만 이는 TCP 기반으로 동작한다면 어쩔 수 없이 안고 가야 하는 문제이다.

 

그렇다면 UDP 기반으로 동작하면 되지 않을까?라는 생각으로 나오게 된 것이 바로 HTTP 3.0이다.

UDP는 TCP보다 기능을 적게 제공해주는 대신 그만큼 Header가 굉장히 가볍기 때문에 다른 기능을 구현할 수 있는 공간이 많다.

따라서 UDP를 기반으로 필요한 기능들을 Application 계층에서 구현하여 UDP가 제공하지 못하는 기능들을 추가적으로 제공해준다.

 

 

HTTP 3.0

 

  • UDP 기반으로 구글에서 개발한 QUIC 프로토콜을 기반으로 개발된 HTTP
  • TCP 통신은 연결이 된 후 데이터를 보내는데 QUIC은 첫 연결 설정에서 필요한 정보와 함께 데이터를 전송하기 때문에 속도가 빠름
  • 3-Way Handshake 방식 해결
  • 또한, 연결 성공 시 설정을 캐싱하여 다음에 연결할 때 사용하여 지속적인 연결이 가능
  • 이는 Connection UUID라는 고유한 식별자로 서버와 연결하기 때문에 커넥션을 재 수립할 필요가 없음
  • TLS를 기본 적용하여 보안성 향상
  • 하나의 Streams이 아닌 독립 Streams을 사용하기 때문에 Stream들은 서로 영향을 주지 않음
  • TCP Head Of Line Blocking 해결

 

 

 

 

[ Reference ]

· https://www.youtube.com/watch?v=xcrjamphIp4

· https://velog.io/@gjrjr4545/HTTP-%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C-%EB%B0%9C%EC%A0%84

반응형

댓글