[웹개발] HTTP 버전별 특징
HTTP 0.9
HTTP 초기에는 버전이 없었으며, 차후 버전과 분리하기 위해 0.9로 불리게 되었다. 가능한 메서드는 GET밖에 없었고, 요청과 응답이 단순하였다.
요청
GET /index.html
응답
<html>
Simple Index Page
</html>
HTTP 헤더가 없었고, HTML 이외의 다른 유형의 문서는 전송될 수 없었다. 상태 오류 코드도 없었기 때문에 문제가 발생한 경우 특정 HTML 파일을 오류에 대한 설명과 함께 보내졌었다.
HTTP 1.0
HTTP 1.0부터 헤더에 메타 정보가 포함되기 시작했다. HTTP 1.0의 특징은 다음과 같다.
- 버전 정보가 GET 라인에 붙은 형태로 전송되기 시작했다.
- 상태 코드가 응답의 시작 부분에 붙어 전송되었고, 그 결과에 대한 동작을 할 수 있게 되었다.
- HTTP 헤더 개념은 요청과 응답을 위해 도입되어, 메타 정보 전송을 허용하고 프로토콜을 유연하고 확장 가능하도록 만들어 주었다.
- Content-Type으로 HTML 파일 외에 다른 문서들을 전송하는 기능이 추가되었다.
HTTP 1.0의 단점으로는 1개의 요청과 1개의 응답이 1개의 Connection과 대응된다는 단점이 있다. 이에 따라 매번 새로운 연결로 성능 저하 및 서버 부하 비용 증가와 같은 문제가 생겼다. 이를 보완하기 위해 등장한 것이 HTTP 1.1이다.
HTTP 1.1
HTTP 1.1의 가장 큰 특징은 사용된 지정한 시간 동안 Connection을 닫지 않는다는 것이다. 그렇게 함으로써 여러 요청이 한 Connection을 사용할 수 있는 것이다.

위 그림을 보면, html 파일과 css 파일을 요청할 때 기존의 Connection을 재사용함으로써 시간을 줄였다. 여기에서 더 나아가 Pipelining이라는 기법이 도입되었다. HTTP 요청은 순차적으로 응답을 받아야 되는데 이는 요청이 많을수록 대기 시간이 길어진다. Pipelining은 응답을 기다리지 않고 순차적인 요청을 연속적으로 보내 그 순서에 맞춰 응답을 받는 방식으로 지연 시간을 줄인다.

그런데 여기서 문제는 다음과 같이 두 요청을 서버가 동시에 처리했을 경우에 발생한다.

위 그림에서 css 파일에 대한 요청이 먼저 처리된다고 해도 HTML 요청이 먼저 도착했기 때문에 HTML 응답이 전송될 때까지 css 응답은 blocking 된다. 이를 HOL(Head-Of-Line) Blocking이라고 하며, 첫 번째 요청이 오래 걸릴 경우 다른 요청이 모두 차단되어 기다려야 하는 매우 비효율적인 상황이 발생하게 된다.
또 다른 문제는 헤더 구조의 중복이다. 요청이 연속적으로 이루어질 때 헤더의 값이 중복되는 게 있는데도 그 데이터를 중복적으로 보내게 된다는 비효율적인 측면이 있다. 이러한 단점들을 보완하기 위해 등장한 것이 HTTP 2.0이다.
HTTP 2.0
HTTP 2.0은 기존 HTTP 1.x 버전의 성능 향상에 초점을 맞춘 프로토콜이라고 할 수 있다. HTTP 1.1의 개선 방안은 다음과 같다.
- Image Spriting : 웹 페이지를 구성하는 다양한 아이콘 이미지 파일의 요청 횟수를 줄이기 위해 아이콘을 하나의 큰 이미지로 만든 다음 CSS에서 해당 이미지의 좌표값을 지정하여 표시하는 것
- Domain Sharing : 요즘 브라우저들은 HTTP 1.1의 단점을 극복하기 위해 여러 개의 Connection을 생성해서 병렬로 요청을 보내기도 한다. 하지만 브라우저별로 도메인당 Connection의 개수가 존재하기 때문에 근본적인 해결책은 아니다.
- Minified CSS / JS : HTTP를 통해 전송되는 데이터의 용량을 줄이기 위해 CSS, JS를 축소하여 적용한다.
그럼 HTTP 2.0의 특징을 살펴보자.
- HTTP 메시지 전송 방식의 변화 : Binary Framing 계층 사용

위 그림을 보면, HTTP 2.0에서는 Binary Framing 계층이 Application 계층 안에 추가된 것을 알 수 있다. HTTP 1.1에서는 텍스트 형식의 메시지를 보냈다면 HTTP 2.0에서는 Frame 단위로 데이터를 분할한다. 그리고 바이너리로 인코딩 후 데이터를 보내게 된다. 그렇게 함으로써 파싱이나 전송 속도가 증가하고 오류가 발생할 가능성이 감소한다는 것이다.
새로운 메커니즘(Binary Framing)이 도입됨에 따라 클라이언트와 서버 간의 데이터 교환 방식이 바뀌었다. 이 과정을 설명하기 위해 HTTP 2.0 용어를 살펴보자.
- 스트림 : 일반적으로 데이터, 패킷, 비트 등의 일련의 연속성을 갖는 흐름 또는 음성, 영상, 데이터 등의 작은 조각들이 하나의 줄기를 이루며 전송되는 데이터 열을 의미한다. 호스트 간 또는 호스트 내 프로세스 간 통신에서 큐에 의한 메시지 전달 방식을 이용한 가상 연결 통로를 의미하기도 한다.
- 메시지 : 논리적 요청 또는 응답 메시지에 매핑되는 프레임의 전체 시퀀스이다.
- 프레임 : HTTP 2.0에서 통신의 최소 단위이며, 각 프레임에는 하나의 프레임 헤더가 포함된다. 이 프레임 헤더는 최소한으로 프레임이 속하는 스트림을 식별한다.
위 용어들의 관계는 다음과 같이 요약된다.
- 모든 통신은 단일 TCP 연결을 통해 수행되며 전달될 수 있는 양방향 스트림의 수는 제한이 없다.
- 각 스트림에는 양방향 메시지 전달에 사용되는 고유 식별자와 우선순위 정보(선택 사항)가 있다.
- 각 메시지는 하나의 논리적 HTTP 메시지(요청, 응답 등)이며 하나 이상의 프레임으로 구성된다.
- 프레임은 특정 유형의 데이터(HTTP 헤더, 메시지 페이로드 등)를 전달한다.
- 다른 스트림들의 프레임을 인터리빙(여러 개의 스트림에서 쪼개진 프레임들을 서로 끼워 넣는 것)한 다음, 각 프레임의 헤더에 삽입된 스트림 식별자를 통해 프레임을 다시 조립할 수 있다.

위 그림을 보면, 스트림 안에서 전송되는 각각의 프레임들이 합쳐져 하나의 응답이나 요청이 되는 것이다.
HTTP 2.0은 HTTP 프로토콜 통신을 바이너리 인코딩 된 프레임의 교환으로 세분화한다. 그런 다음 이 프레임은 특정 스트림에 속하는 메시지에 매핑되며, 모든 프레임은 단일 TCP 연결 내에서 다중화된다. HTTP 2.0 프로토콜이 제공하는 다른 모든 기능과 성능 최적화는 이러한 기반을 통해 지원된다.

위 그림을 보면, 스트림 1, 3, 5 스트림이 동시에 병렬적으로 하나의 연결 안에서 이루어지는 것을 알 수 있다. 이로써 응답 다중화를 가능하게 하고 위에서 언급했던 HOL Blocking 문제를 해결할 수 있다. 또한 여러 개의 연결이 없어도 되기 때문에 리소스 비용이 더 절감될 수 있다는 장점이 있다.
HTTP 2.0의 또 다른 특징으로는 스트림 우선순위가 있다. HTTP 메시지가 많은 개별 프레임으로 분할될 수 있고, 여러 스트림의 프레임을 다중화할 수 있게 되면서 스트림들의 우선순위로를 지정할 필요가 생겼다. 클라이언트는 우선순위 지정을 위해 우선순위 지정 트리를 사용하여 서버의 스트림 처리 우선순위를 지정할 수 있다. 서버는 우선순위가 높은 응답이 클라이언트에 우선적으로 전달될 수 있도록 대역폭을 설정한다.
HTTP 2.0 정리
- Multiplexed Streams : 한 개의 Connection으로 동시에 여러 개의 메시지를 주고받을 수 있고, 응답은 순서에 상관없이 스트림으로 주고받는다.
- Stream Priortization : 리소스 간의 의존관계에 따른 우선순위를 설정하여 리소스 로드 문제를 해결한다.
- Server Push : 클라이언트가 HTML 문서를 요청할 때 해당 문서 내의 리소스를 사전에 다운로드할 수 있도록 하여 클라이언트의 요청을 최소화할 수 있다.
- Header Compression : Header Table과 허프만 인코딩 기법을 사용하여 처리하는데 이를 HPACK 압축방식이라 부른다. 헤더 중복이 있는 경우 Static / Dynamic Header Table 개념을 이용하여 중복을 검출해내고 해당 테이블에서 Index 값 + 중복되지 않은 Header 정보를 허프만 인코딩 방식으로 인코딩한 데이터를 전송한다.