ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [HTTP 완벽 가이드] 10장. HTTP/2.0
    Engineering/Network 2021. 10. 16. 23:24
    반응형

    HTTP/2.0

    HTTP/2.0 의 등장 배경

    • HTTP/1.1의 메시지 포맷은 구현의 단순성과 접근성에 주안점을 두고 최적화되었다.
    • HTTP/1.1은 커넥션 하나를 통해 요청 하나를 보내고 그에 대한 응답 하나만을 받는 방식이다.
    • 응답을 받아야만 다음 요청을 보낼 수 있기 때문에 회전 지연(latency)을 피할 수 없다. 이 문제를 피하기 위해 병렬 커넥션이나 파이프라인 커넥션이 도입되었지만 성능 개선에 근본적인 해결책은 되지 못했다.
    • 이를 해결하기 위해 구글은 SPDY 프로토콜을 개발했다.
    • SPDY 프로토콜은 헤더를 압축하여 대역폭을 절약하고, 클라이언트가 요청을 보내지 않아도 서버가 능동적으로 리소스를 푸시하는 기능도 갖추고 있다.
    • HTTP/2.0 은 SPDY를 기반으로 설계되었다.

    개요

    • HTTP/2.0은 서버와 클라이언트 사이의 TCP 커넥션 사이에서 동작한다.

    • HTTP/2.0 요청과 응답은 길이가 정의된(최대 16383바이트) 한 개 이상의 프레임에 담긴다. 이떄 HTTP 헤더는 압축되어 담긴다.
    • 프레임들에 담긴 요청과 응답은 스트림을 통해 보내지며, 한 개의 스트림이 한 쌍의 요청과 응답을 처리한다.
    • 하나의 커넥션 위에 여러 개의 스트림이 동시에 만들어 질 수 있으므로, 여러 개의 요청과 응답을 동시에 처리하는 것이 가능하다.
    • HTTP/2.0은 스트림에 대한 흐름 제어와 우선순위 부여 기능을 제공한다.
    • HTTP/2.0은 기존의 요청/응답과는 다르게 서버 푸시 모델을 도입했다.
    • 기존 웹 애플리케이션들과의 호환성을 유지하기 위해, HTTP/2.0은 요청과 응답 메시지의 의미를 HTTP/1.1과 같도록 유지하고 있다.
      • 다만 헤더를 표현하는 방법이 변경되었다. (의미는 같다.)
      • 'Content-Length' 헤더는 HTTP/2.0에서 ':content-length'
      • 상태줄을 통해 표현하던 404 Not Found는 '404' 값을 갖고 있는 ':status' 헤더로 표현하게 되었다.

    바이너리 프레이밍 계층

    • 바이너리 프레이밍 계층은 HTTP 메시지가 캡슐화되어 클라이언트와 서버 사이에 전송되는 방식을 규정한다.

    • 줄바꿈으로 구분되는 일반 텍스트 HTTP/1.x 프로토콜과 달리, 모든 HTTP/2 통신은 더 작은 메시지와 프레임으로 분활되어 바이너리 형식으로 인코딩된다.
    • HTTP/1.x 클라이언트는 HTTP/2 전용 서버를 이해하지 못하며 그 반대도 마찬가지이다. 하지만 필요한 모든 프레이밍 작업을 클라이언트와 서버가 대신 수행해주기 때문에 애플리케이션은 이 모든 변경을 인식하지 않아도 된다.

    스트림, 메시지, 프레임

    • 스트림: HTTP/2.0 커넥션을 통해 클라이언트와 서버 사이에 교환되는 프레임들의 독립된 양방향 시퀀스이며, 하나 이상의 메시지가 전달될 수 있다.
    • 메시지: 논리적 요청 또는 응답 메시지에 매핑되는 프레임의 전체 시퀀스이다.
    • 프레임: HTTP/2.0에서 통신의 최소 단위이며 각 최소 단위에는 하나의 프레임 헤더가 포함된다. 프레임 헤더는 최소한으로 프레임이 속하는 스트림을 식별한다.
    • 모든 통신은 단일 TCP 연결을 통해 수행되며 전달될 수 있는 양방향 스트림의 수는 제한이 없다.
    • 각 스트림에는 양방향 메시지 전달에 사용되는 고유 식별자와 우선순위 정보(선택 사항)이 있다.
    • 각 메시지는 하나의 논리적 HTTP 메시지(ex: 요청 or 응답)이며 하나 이상의 프레임으로 구성된다.
    • 프레임은 통신의 최소 단위이며 특정 유형의 데이터(ex: HTTP 헤더, 메시지 페이로드 등)을 전달한다. 다른 스트림들의 프레임을 인터리빙한 다음, 각 프레임의 헤더에 삽입된 스트림 식별자를 통해 이 프레임을 다시 조립할 수 있다.


    하나의 커넥션에 여러 스트림이 동시에 열릴 수 있으므로 여러 개의 요청을 동시에 보낼 수 있으므로 성능이 뛰어나다.

    • 한번 사용한 스트림 식별자는 다시 사용할 수 없기 때문에 커넥션을 오래 사용하다보면 스트림에 할당할 수 있는 식별자가 고갈되기도 하는데, 그런 경우엔 커넥션을 다시 맺으면 된다.

    서버 푸시

    • HTTP/2.0은 서버가 단일 클라이언트 요청에 대해 여러 응답을 보낼 수 있다.
    • 리소스를 푸시하려는 서버는 먼저 클라이언트에게 자원을 푸시할 것임을 PUSH_PROMISE 프레임을 보내어 미리 알려주어야 한다.
    • PUSH_PROMISE 프레임은 리소스를 요청하는 응답 데이터보다 먼저 도착해야 한다.
    • 리소스에 대해 중복 요청이 생성되는 것을 막기 위해 클라이언트는 서버가 어떤 리소스를 푸시할지 알아야 하고, 이러한 요구사항을 충족시키기 위해 약속했던 리소스의 HTTP 헤더만 포함된 모든 PUSH_PROMISE 프레임을 상위 요소의 응답(DATA 프레임)보다 먼저 전송한다.
    • 클라이언트는 PUSH_PROMISE 프레임을 수신한 후에 RST_STREAM 프레임을 보내어 푸시를 거절할 수 있다.

    참고자료

    HTTP 완벽 가이드

    https://developers.google.com/web/fundamentals/performance/http2?hl=ko

    반응형

    댓글

Designed by Tistory.