HTTP/1.1과 HTTP/2
간단한 소개
HTTP는 1996년 처음 버전이 release 되었으며, 1999년 현재 우리가 공식적으로 가장 많이 사용하고 지원하는 버전 1.1이 출시된 이후 15년동안 발전없이 사용되어 왔다. HTTP 1.1 스펙으로는 다량의 멀티미디어 리소스를 처리하는 부분에서나, 웹페이지 하나를 구성하기 위한 다수의 비동기 요청발생을 컨트롤하기에 힘들다.
HTTP/1.1 동작방식
HTTP는 Hyper Text Transfer Protocol의 두문자어로 인터넷에서 데이터를 주고받을 수 있는 프로토콜이다.
HTTP 1.1 protocol은 클라이언트와 서버간 통신을 위해 GET require -> Response의 형태로, 즉 요청을 하면 응답을 하고, 또 다른 요청이 있으면 반응을 하는 순차적인 형태였다. 이 말은 기본적으로 Connection당 하나의 요청을 처리하도록 설계되어 있다는 뜻이다. 이는 동시전송이 불가능하고 요청과 응답이 순차적으로 이루어진다는 것이다.
이는 HTTP문서 안에 포함된 다수의 리소스를 처리하려면 요청할 리소스 개수에 비례하여 대기 시간이 길어진다는 의미가 된다. 더 나아가 HTTP/1.1의 형태에서 단점을 알아보도록 하자
HOL (Head Of Line) Blocking
특정 응답의 지연.
Web환경에서 HOLB는 두 종류로 존재하며, 이는 HTTP의 HOL Blocking / TCP의 HOL Blocking이다. 여기서 우리는 HTTP의 HOL Blocking을 알아본다. 위에서 설명했듯이 HTTP/1.1은 connection당 하나의 요청을 처리하는데 이를 개선할 수 있는 기법중에 pipelining이 존재한다. 이것은 Connection을 통해 다수 개의 파일을 요청 / 응답 받을 수 있는 기법을 말하며, 이 기법을 통해 어느정도의 기능 향상을 꾀할 수 있다.
하지만 하나의 TCP연결에서 3개의 이미지를 얻으려고 하는 경우, HTTP의 요청순서는 다음의 형태와 같다.
|--------- a.png ---------|
|--------- b.png ---------|
|--------- c.png ---------|
이와 같이 첫번째 이미지가 요청되고, 응답받고 다음 이미지를 요청하게 되는데 만약 첫번째 이미지를 요청하고 응답이 지연되면 아래 그림과 같이 두 세번째 이미지는 첫번째 이미지의 응답처리가 완료되기 전까지 대기하게 되며 이와 같은 현상을 HTTP의 Head of Line Blocking이라 부르는 것이다.
|---------------------------- a.png ----------------------------|
|--------- b.png ---------|
|--------- c.png ---------|
RTT(Round Trip Time) 증가
HTTP/1.1의 경우 일반적으로 하나의 connection에 하나의 요청을 처리 한다. 이는 매 요청별로 connection을 만들게 되고, TCP상에 동작하는 HTTP의 특성상 3-way Handshake가 반복적으로 일어나고 또한 불필요한 RTT증가와 네트워크 지연을 초래하여 성능을 저하시킨다.
무거운 Header 구조
HTTP/1.1의 header에는 많은 메타정보들이 있다. 사용자가 방문한 웹페이지는 다수의 http 요청이 발생하게 되는데, 이 경우 매 요청시마다 중복된 헤더 값을 전송하게 되며, 또한 해당 domain에 설정된 cookie정보도 매 요청시마다 header에 포함되어 전송되며 때마다 요청을 통해 전송하려는 값보다 header 값이 더 큰 경우도 비일비재하다.
HTTP/2
2012년 10월부터 시작한 새로운 프로토콜 구현 프로젝트인 http2의 github 서문을 살펴보자
HTTP/2 is a replacement for how HTTP is expressed “on the wire.” It is not a ground-up rewrite of the protocol; HTTP methods, status codes and semantics are the same, and it should be possible to use the same APIs as HTTP/1.x (possibly with some small additions) to represent the protocol. The focus of the protocol is on performance; specifically, end-user perceived latency, network and server resource usage. One major goal is to allow the use of a single connection from browsers to a Web site.
여기서 중요한 키 포인트는 다음과 같다.
- HTTP/2는 HTTP가 유선상에서 표현 방법을 대치하는 것이다.
- 이것은 프로토콜을 완전히 다시 작성하는 것이 아니라 HTTP 메소드, 상태 코드 및 의미는 동일하며 프로토콜을 나타내기 위해 HTTP/1.x와 동일한 API를 사용할 수 있어야 한다.
- HTTP/2의 초점은 성능이다. 특히 최종 사용자가 대기 시간, 네트워크 및 서버 리소스 사용을 인식한다.
- 브라우저에서 웹 사이트로의 단일 연결을 허용하는 것이 주요 목표이다.
즉, 새로운 방식의 프로토콜이 아닌, 성능향상에 초점을 맞춘 프로토콜이 HTTP/2라는 것이다. 그러면 HTTP/2의 기술을 알아보도록 하자.
Multiplexed Streams
한 Connection으로 동시에 여러 개의 메시지를 주고 받을 수 있으며, 응답은 순서에 상관없이 stream으로 주고 받는다. HTTP/1.1의 Connection keep-Alive, Pipelining의 개선이라고 보면 된다.
Stream Pripritization
클라이언트가 요청한 HTML문서 안에 CSS파일 1개와 Image파일 2개가 존재하고, 이를 클라이언트가 각각 요청하고 난 후에 Image파일보다 CSS파일의 수신이 늦어지는 경우 브라우저의 렌더링이 늦어지는 문제가 발생하는 부분을 HTTP/2에서는 리소스간 의존관계(우선순위)를 설정하여 이런 문제를 해결하고 있다.
Server Push
서버는 클라이언트의 요청에 대해 요청하지도 않은 리소스를 마음대로 보내줄 수도 있다.
이는, 클라이언트 즉, 브라우저가 HTML문서를 요청했고, 해당 HTML에 여러 개의 리소스가 포함되어 있는 경우 HTTP/1.1에서 클라이언트는 요청한 HTML문서를 수신한 후 HTML문서를 해석하면서 필요한 리소스를 재 요청하는 반면, HTTP/2에서는 Server Push기법을 통해 클라이언트가 요청하지도 않은 리소스를 Push해주는 방법으로 클라이언트의 요청을 최소화해서 성능 향상을 이끌어 낸다.
Header Compression
HTTP/2는 Header의 정보를 압축하기 위해 Header Table과 Huffman Encoding기법을 사용하여 처리하는데 이를 HPACK 압축방식이라 부르며 별도의 명세서(RFC 7531)로 관리하고 있다. 클라이언트가 두 번의 요청을 보낸다고 가정하면 HTTP/1.x의 경우 두 개의 요청 Header에 중복 값이 존재해도 그냥 중복 전송한다. 하지만 HTTP/2에서는 Header에 중복 값이 존재하는 경우 Static/Dynamic Header Table 개념을 사용하여 중복 Header를 검출하고 중복된 Header는 index값만 전송하고 중복되지 않은 Header정보의 값은 Huffman Encoding 기법으로 인코딩처리하여 전송한다.
Reference
https://www.popit.kr/%EB%82%98%EB%A7%8C-%EB%AA%A8%EB%A5%B4%EA%B3%A0-%EC%9E%88%EB%8D%98-http2/