본문 바로가기

HTTP 완벽 가이드

[HTTP 완벽 가이드] HTTP 2.0

 

 

1) HTTP 2.0 등장 배경

 

- HTTP/1.1의 메시지 포맷은 구현의 단순성과 접근성에 주안점을 두고 최적화되었다
  그러다 보니 성능은 어느 정도 희생시키지 않을 수 없었다

 

- 커넥션 하나를 통해 요청 하나를 보내고 그에 대해 응답 하나만을 받는 HTTP의 메시지 교환 방식

   단순함 면에서는 더할 나위 없었지만, 

   응답을 받아야만 그 다음 요청을 보낼 수 있기 때문에 심각한 회전 지연(latency)을 피할 수 없었다

 

-  이 문제를 회피하기 위해 병렬 커넥션이나 파이프라인 커넥션이 도입되었지만

   성능 개선에 대한 근본적인 해결책은 되지 못했다.

-  2009년, 구글은 웹을 더 빠르게 하겠다는 목표 아래 SPDY 프로토콜을 내놓았다
    SPDY는 기존의 HTTP에 속도를 개선하기 위한 여러 기능을 추가한 것이다
    SPDY는

   (1) 헤더를 압축하여 대역폭을 절약했고, 

   (2) 하나의 TCP 커넥션에 여러 요청을 동시에 보내 회전 지연을 줄이는 것이 가능했으며,
   (3) 클라이언트가 요청을 보내지 않아도 서버가 능동적으로 리소스를 푸시

   하는 기능도 갖추고 있다.

- 이 모두는 회전 지연을 줄이기 위한 것이다.

   구글의 "SPDY: 더 빠른 웹을 위한 실험적인 프로토콜"에 따르면,
   SPDY를 적용했을 때, RTT가 20ms인 상황에서는 12.34%의 성능 개선 효과가 있었으며,
   80ms인 상황에서는 23.85%, 200ms인 상황에서는 26.79%의 성능 개선 효과가 있었다

- 마침내 2012년 10월 3일, HTTP 작업 그룹은 SPDY를 기반으로 

   HTTP/2.0 프로토콜을 설계하기로 결정하였음을 메일링 리스트를 통해 밝혔다
   HTTP 작업 그룹은 SPDY의 초안을 그대로 가져와서 HTTP/2.0의 초안을 만들기 시작했다

- 2013년 11월 현재, HTTP/2.0은 여덟 번째 초안까지 나와 있으며, 

   아직까지는 SPDY의 특징들을 거의 그대로 유지하고 있다
   크게 변경된 점이라면 헤더를 압축할 때 더 이상 deflate 알고리즘을 사용하지 않게 되었다는 것 정도다.

 

 

2) HTTP 2.0이란?

- HTTP/2.0은 서버와 클라이언트 사이의 TCP 커넥션 위에서 동작한다
  이 때, TCP 커넥션을 초기화하는 것은 클라이언트다

- HTTP/2.0 요청과 응답은 길이가 정의된 한 개 이상의 프레임에 담긴다
  이 때, HTTP 헤더는 압축되어 담긴다
  프레임들에 담긴 요청과 응답은 스트림을 통해 보내진다
  한 개의 스트림이 한 쌍의 요청과 응답을 처리한다
  하나의 커넥션 위에 여러 개의 스트림이 동시에 만들어질 수 있으므로,

  여러 개의 요청과 응답을 동시에 처리하는 것 역시 가능하다
   HTTP/2.0은 이들 스트림에 대한 흐름 제어와 우선순위 부여 기능도 제공한다

- HTTP/2.0은 기존의 요청-응답과는 약간 다른 새로운 상호작용 모델인 서버 푸시를 도입했다
  이를 통해 서버는 클라이언트에게 필요하다고 생각하는 리소스라면 그에 대한 요청을 명시적으로 받지 않더라도
  능동적으로 클라이언트에게 보내줄 수 있다

- 기존 웹 애플리케이션들과 호환성을 최대한 유지하기 위해, 

   HTTP/2.0은 요청과 응답 메시지의 의미를 HTTP/1.1과 같도록 유지하고 있다
   HTTP/1.1에서와 마찬가지로 HTTP/2.0에서도 Content-Length 헤더는 본문의 길이를 의미하며,

   404 Not Found 응답은 리소스를 찾을 수 없음을 의미한다
   다만, 이를 표현하는 문법은 변경되었다

 

 


3 HTTP/1.1과의 차이점


(1) 스트림과 멀티플렉싱


- 스트림은 HTTP/2.0 커넥션을 통해 클라이언트와 서버 사이에서 교환되는 

  프레임들의 독립된 양방향 시퀀스다

 

- 한 쌍의 HTTP 요청과 응답은 하나의 스트림을 통해 이루어진다.

  클라이언트는 새 스트림을 만들어 그를 통해 HTTP 요청을 보낸다.
  요청을 받은 서버는 그 요청과 같은 스트림으로 응답을 보낸다
   그러고 나면 스트림이 닫히게 된다

- HTTP/1.1에서는 한 TCP 커넥션을 통해 요청을 보냈을 때, 

  그에 대한 응답이 도착하고 나서야 같은 TCP 커넥션으로 다시 요청을 보낼 수 있다
  따라서 웹브라우저들은 회전 지연을 줄이기 위해 여러 개의 TCP 커넥션을 만들어

  동시에 여러 개의 요청을 보내는 방법을 사용한다

 

- 그러나 그렇다고 TCP 커넥션을 무한정 만들 수는 없기에   

   한 페이지에 보내야 할 요청이 수십에서 수백에 달하는 오늘날에는 회전 지연이 늘어나는 것을 피하기 어렵다
   파이프라인 커넥션을 통해 이것을 피할 수는 있으나 그다지 널리 구현되어 있지 않다

그러나 HTTP/2.0에서는 하나의 커넥션에 여러 개의 스트림이 동시에 열릴 수 있다
   따라서 하나의 HTTP/2.0 커넥션을 통해 여러 개의 요청이 동시에 보내질 수 있기 때문에

   이 문제는 쉽게 해결될 수 있다

 

- 뿐만 아니라 스트림은 우선순위도 가질 수 있다
  예를 들어, 사용자가 웹브라우저로 어떤 웹페이지를 보려고할 때,

  네트워크 대역폭이 충분하지 않아 프레임의 전송이 느리다면,
  웹브라우저는 보다 중요한 리소스를 요청하는 스트림에게 더 높은 우선순위를 부여할 수 있을 것이다
  그러나 이 우선순위에 따르는 것은 의무사항이 아니기 때문에, 요청이 우선순위대로 처리된다는 보장은 없다


(2) 헤더 압축
 
- HTTP/1.1에서 헤더는 아무런 압축 없이 그대로 전송되었다
   과거에는 웹페이지 하나를 방문할 때의 요청이 많지 않았기 때문에

   헤더의 크기가 그다지 큰 문제가 되지 않았지만,
   요즈음에는 웹페이지 하나를 보기 위해 수십에서 많으면 수백 번의 요청을 보내기 때문에,
   헤더의 크기가 회전 지연과 대역폭 양쪽 모두에 실질적인 영향을 끼치게 되었다

이를 개선하기 위해 HTTP/2.0에서는 HTTP 메시지의 헤더를 압축하여 전송한다
  헤더는 HPACK 명세에 정의된 헤더 압축 방법으로 압축된 뒤 '헤더 블록 조각'들로 쪼개져서 전송된다
  받는 쪽에서는 이 조각들을 이은 뒤 압축을 풀어 원래의 헤더 집합으로 복원한다

- HPACK은 헤더를 압축하고 해제할 때 '압축 콘텍스트'를 사용한다
  따라서 오동작하지 않으려면 항상 올바른 압축 콘텍스트를 유지해야 한다
  이 압축 콘텍스트는 수신한 헤더의 압축을 풀면 이에 영향을 받아 바뀐다.
  송신 측은 수신 측이 헤더의 압축을 풀었으며,

  그에 따라 압축 콘텍스트가 변경되었다고 가정할 것이다

- 따라서 헤더를 받은 수신 측은 어떤 경우에도 반드시 압축 해제를 수행해야 한다
  만약 그럴 수 없다면 반드시 COMPRESSION_ERROR와 함께 커넥션을 끊어야 한다


(3) 서버 푸시  

- HTTP/2.0은 서버가 하나의 요청에 대해 응답으로 여러 개의 리소스를 보낼 수 있도록 해준다
  이 기능은 서버가 클라이언트에서 어떤 리소스를 요구할 것인지 미리 알 수 있는 상황에서 유용하다
  예를 들어, HTML 문서를 요청 받은 서버는 그 HTML 문서가 링크하고 있는

  이미지, CSS 파일, 자바스크립트 파일 등의 리소스를 클라이언트에게 푸시할 수 있을 것이다

 

- 이는 클라이언트가 HTML 문서를 파싱해서 필요한 리소스를 다시 요청하게 발생하게 되는

  트래픽과 회전 지연을 줄여준다

리소스를 푸시하려는 서버는 먼저 클라이언트에게 자원을 푸시할 것임을 

   PUSH_PROMISE 프레임을 보내어 미리 알려주어야 한다
  클라이언트가 PUSH_PROMISE 프레임을 받게 되면 해당 프레임의 스트림은

   클라이언트 입장에서는 예약됨 상태가 된다
   이 상태에서 클라이언트는 RST_STREAM 프레임을 보내어 푸시를 거절할 수 있다

- RST_STREAM을 보내게 되면 그 스트림을 즉각 닫히게 된다
  스트림이 닫히기 전까지 클라이언트는 서버가 푸시하려고 하는 리소스를 요청해서는 안된다

- 이와 같이 사전에 PUSH_PROMISE 프레임을 먼저 보내는 이유는 

  서버가 푸시하려고 하는 자원을 클라이언트가 별도로 또 요청하게 되는 상황을 피하기 위함이다.









'HTTP 완벽 가이드' 카테고리의 다른 글

[HTTP 완벽 가이드] 캐시  (0) 2024.06.21