본문 바로가기

공부

HTTP 2.0

 

 

HTTP 1.1

HTTP Pipelining

HTTP 1.0은 기본적으로 Connection 당 하나의 요청을 처리할 수 있습니다.

그렇기 때문에 동시전송은 불가능하고 하나의 요청에 대한 응답이 온 후 다음 요청을 처리하게 됩니다.

위에서도 말했듯이 수 많은 멀티미디어 리소스들이 있는 상황에서 이러한 특징은 Network Latency를 발생시킵니다.

 

이를 위해 HTTP 1.1에서 HTTP Pipelining 이 도입되었습니다.

이는 TCP 안에 두 개 이상의 HTTP 요청을 담아 Network Latency을 줄이는 방식입니다.

하지만 이는 정확히 구현하기 힘들 뿐 아니라 HOL Blocking이 발생합니다.

 

HOL Blocking

HOL은 Head of Line의 줄임말로서 앞선 요청에 의해 뒤에 요청이 지연되는 것을 의미합니다.

HTTP Pipelining 을 통해 한 번에 여러 개의 이미지를 요청하는 경우를 생각해봅시다.

가장 앞에 요청한 이미지가 응답이 지연되면 두, 세번째 이미지도 지연이 발생합니다.

TCP 안에 여러 개의 HTTP 요청이 왔으므로 완료된 응답부터 보내면 되지 않을까라고 생각할 수 있지만 서버는 TCP에서 요청을 받은 순서대로 응답을 해야합니다.

 

무거운 Header

클라이언트와 서버 간에 수 많은 http 요청이 발생할 것이고 header의 정보는 대부분 동일합니다.

하지만 HTTP 1.1에서는 이러한 헤더를 중복해서 계속 보낼 뿐 아니라 cookie 정보 역시 매 요청마다 헤더에 포함되어 전송됩니다.

즉 불필요한 데이터를 주고 받는데 네트워크 자원이 소비되는 문제가 발생합니다.

 

HTTP 2.0이 등장하기 이전에

HTTP 2.0이 등장하기 전, 개발자들이 마냥 손 놓고 있지만은 않았습니다.

HTTP 1.1 안에서 위에서 봤던 문제점을 극복하기 위해 노력했습니다.

 

Image Spriting

여러 이미지 파일들에 대해 각각 요청을 하기 보다 한 번에 요청으로 끝내기를 택했습니다.

여러 이미지를 모아 하나의 큰 이미지를 만든 후, CSS로 해당 이미지의 좌표값을 지정해서 사용합니다.

 

Domain Sharding

하나의 Domain에 대해 여러 개의 Connection을 생성하여 병렬로 요청을 보냅니다.

하지만 브라우저 별로 Domain당 Connection 개수의 제한이 존재하므로 근본적인 해결책이 될 수 없습니다.

 

CSS, Javascript 최소화

전송되는 데이터의 용량을 줄이기 위해 CSS, Javascript 파일을 최소화하여 통신합니다.

 

 

HTTP 2.0

HTTP 2.0은 HTTP를 아예 새롭게 개선하기 보다는 기존 HTTP 1.1을 개선하는 방향에서, 성능 쪽에 초점을 맞춘 프로토콜로서2015년 2월 표준으로 승인되었습니다.

HTTP 1.1의 여러 문제점으로 구글이 개발한 비표준 개방형 프로토콜 SPDY를 기반하였습니다.

 

 

Multiplexed Streams

HTTP 1.1의 HTTP Pipelining 의 개선안으로 하나의 Connection으로 동시에 여러 개의 메세지를 주고 받을 수 있습니다.

또한 응답은 요청 순서에 상관없이 Stream으로 받기 때문에 HOL Blocking 도 발생하지 않습니다.

Multiplexed Streams

위의 이미지 처럼, 하나의 커넥션에서 여러 병렬 스트림(3개)이 존재 할 수 있습니다. stream이 뒤섞여서 전송 될 경우, stream number를 이용해 수신측에서 재조합됩니다.

 

Stream Prioritization

응답에 대한 우선순위를 정해 우선순위가 높을수록 응답을 빨리 합니다.

예를 들어 하나의 HTML 문서에 CSS 파일과 여러 IMG 파일이 있다고 가정해봅시다.

만일 여러 IMG 파일을 응답하느라 CSS 파일의 응답이 느려지면 클라이언트는 렌더링을 하지 못하고 기다리게 됩니다.

따라서 CSS 파일의 우선순위를 올려 렌더링을 진행하며 IMG 파일은 도착하는 대로 띄어준다면 더 효율적입니다.

 

Server Push

서버가 클라이언트의 요청없이 응답을 보내는 방법입니다.

위와 마찬가지로 하나의 HTML 문서에 CSS 파일과 여러 IMG 파일이 있다고 가정해봅시다.

기존에는 HTML 문서를 요청한 후 다시 각각의 CSS 파일과 여러 IMG 파일을 위한 요청을 보내야 했습니다.

하지만 Server Push 로 인해서 클라이언트의 요청을 최소화하고 서버가 리소스를 알아서 보내줍니다.

 

Header Compression

HTTP 1.1의 경우 이전 요청과 중복되는 Header도 똑같이 전송하느라 네트워크 자원을 불필요하게 낭비하였습니다.

HTTP 2.0의 경우, Header Table과 Huffman Encoding을 사용하는 HPACK 압축방식으로 이를 개선하였습니다.

클라이언트와 서버는 각각 Header Table을 관리하고 이전 요청과 동일한 필드는 table의 index만 보내고, 변경되는 값은 Huffman Encoding 후 보냄으로서 Header의 크기를 경령화 하였습니다.

 

Header Compression

 

HTTP 2.0의 장점 정리

  1. Multiplexed Streams - 한 커넥션에 여러개의 메시지를 동시에 주고받을 수 있고, 응답은 순서에 상관없이 stream으로 주고 받음
  2. 요청이 커넥션 상에서 다중화되므로 HOL(Head Of Line) Blocking이 발생하지 않음 
  3. Stream Prioritization(요청 리소스 간 의존관계를 설정) - 클라이언트가 요청한 HTML 문서 안에 CSS 파일 1개와 Image 파일 2개가 존재하고, 이를 클라이언트가 각각 요청한 후, Image 파일 보다 CSS 파일의 수신이 늦어지는 경우, 브라우저의 렌더링이 늦어지는 문제가 발생한다. HTTP/2의 경우 리소스 간 의존 관계(우선 순위)를 설정해 이런 문제를 해결
  4. Header Compression(Header 정보를 HPACK 압축 방식을 이용하여 압축 전송) - HTTP/2에서는 Header에 중복값이 존재하는 경우, Static/Dynamic Header Table 개념을 사용하여 중복 Header를 검출하고, 중복된 Header는 index 값만 전송하고 중복되지 않은 Header 정보의 값은 Huffman Encoding 기법으로 인코딩 처리하여 전송 
  5. Server Push(HTML 문서 상에 필요한 리소스를 클라이언트 요청없이 보내줄 수 있음) - 클라이언트가 HTML 문서를 요청하고 해당 HTML에 여러 개의 리소스(CSS, Image,...)가 포함되어 있는 경우, HTTP/1.1에서는 클라이언트는 요청한 HTML 문서를 수신한 후, HTML 문서를 해석하면서 필요한 리소스를 재요청하는 반면, HTTP/2에서는 Server Push 기법을 통해 클라이언트가 요청하지 않은 리소스를 push해주는 방법으로 클라이언트의 요청을 최소화하여 성능 향상을 이끌어냈다. PUSH_PROMISE라고 부르며, PUSH_PROMISE를 통해 서버가 전송한 리소스에 대해서 클라이언트는 요청하지 않음
  6. 프로토콜 협상 메커니즘 - 프로토콜 선택. like HTTP / 1.1, HTTP / 2 또는 기타 
  7. HTTP / 1.1과의 높은 수준의 호환성 - 메소드, 상태코드, URI 및 헤더 필드
  8. 페이지 로딩 속도 향상

하지만, HTTP/2는 여전히 TCP를 이용하기 때문에 HandShake의 RTT(Round Trip Time)로 인한 Latency(지연 시간), TCP의 HOL Blocking은 해결할 수 없습니다.

 

그래서 HTTP/3가 등장했습니다!

 

레퍼런스

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

https://kinsta.com/learn/what-is-http2/

'공부' 카테고리의 다른 글

[next.js] useRouter vs Router 차이  (0) 2022.09.09
Edge Computing (FeConf 2022)  (0) 2022.09.02
HTTP 1.1 Connection  (0) 2022.08.15
HTTP 리다이렉션과 부하균형  (0) 2022.07.31
HTTP 쿠키  (0) 2022.07.17