⚡HTTP 진화 과정
페이지를 열고, 개발자 도구에서 네트워크 탭을 통해서 확인한 프로토콜의 정보이다. (어떤 페이지에서든 확인 가능)
위 사진의 프로토콜 컬럼을 보면 http/1.1, h2, h3 를 확인할 수 있다. 이는 각 통신이 HTTP/1.1, HTTP/2, HTTP/3 을 이용했다는 것을 알 수 있다.
여기서의 의문점은 하나의 웹 페이지에서 서로 다른 버전의 HTTP가 사용되고 있다는것이다.
그래서 이번에 정리해볼 내용의 경우 HTTP의 배경과 버전별 특징을 정리해보려고 한다. 왜 이렇게 변화가 되었는지를 알아야 기억하기도 편하다고 생각이 된다.
HTTP/1.1전에 HTTP/1.0과 HTTP/0.9 라는 두 개의 버전이 더 있지만, 이 부분의 경우 좀 더 깊게 공부하고 싶은 경우 추천한다.
간단하게 설명해보자면
- HTTP/0.9 : 문서화된 최초의 HTTP 버전
- HTTP/1.0 : 기존 HTTP의 기능을 확장한 버전 (처음으로 널리 사용하기 시작한 버전)
- HTTP/1.0+ : keep alive 커넥션, 프락시 연결 지원 등의 기능이 추가되었다.
- HTTP/1.1 : 표준화된 HTTP
초창기의 웹의 경우, 단순한 서버 - 클라이언트 구조를 따랐다. 클라이언트에서 HTML을 서버에 HTTP 규격에 맞춰 요청을 하게 되면 서버가 그에 맞는 HTML을 전송하는 것이 전부였다. 이렇게 된 이유는 웹의 경우 대학과 연구소를 위한 학술적 정보를 저장하고 교환하는 목적으로 제안되었기 때문에 HTTP를 설계할 때 복합한 최적화 사항들까지는 신경 쓸 필요가 없었기 때문이다. 그러다 보니 HTTP의 구조는 매우 간단했다.
HTTP/0.9 방식을 이용한 요청과 응답 예시.
/* 요청 */
GET /mypage.html
/* 응답 */
<HTML>
A very simple HTML page
</HTML>
예전의 HTTP/0.9의 방식은 위의 예시처럼 GET 방식으로 HTML을 요청하고, 그에 맞는 HTML을 응답받는 아주 간단한 형식이었다. 하지만 웹의 인기가 늘어나게 되면서 기존의 HTTP 사양만으로는 사용자의 요구사항을 충족시킬 수 없게 되었다. 그러다 보니 여러 브라우저 및 웹 서버 벤더는 각자 HTTP에 여러 가지 기능을 추가하게 되었다. 당시에는 서로 약속이 없었기 때문에 각 클라이언트와 서버의 기능이 일관성이 있게 구현이 되지 않아서 문제가 일어나게 된다. 그래서 HTTP의 기본적인 구조는 그대로 유지하면서 다양한 요구사항을 충족시키고 표준화하기 위해서 HTTP WG(Working Group)이라는 조직이 탄생하게 된다. HTTP WG은 1996년에 이르러서야 이러한 사양을 정리하여 발표했는데, 이를 HTTP/1.0이라 부릅니다. 이렇게 새로 발표된 HTTP/1.0을 구별하기 위해 최초의 버전에는 HTTP/0.9라는 이름을 붙였다
HTTP/1.0 주요 내용 (중요❗❗)
- 버전 정보가 명시되었고 각 요청﹒ 응답 사이에서 전송되었습니다.
- 요청 메서드가 GET, HEAD, POST 세 가지로 확장되었습니다.
- 상태 코드가 추가되어 클라이언트 측에서 요청 결과에 따라 동작할 수 있게 되었습니다.
- 요청과 응답에 대한 부가적인 메타데이터를 담는 헤더 필드가 추가되었습니다.
- HTTP 헤더(Content-Type)의 도움으로 HTML 이외의 파일도 전송할 수 있게 되었습니다.
- 커넥션 하나당 요청 하나와 응답 하나만 처리 가능했음
-> 지금 생각해보면 매우 비효율적인 동작으로 보이며, 서버 부하도 문제
-> HTTP 1.1에서 개선
HTTP/1.0 방식을 이용한 요청과 응답 예시.
<!-- 요청 -->
GET /mypage.html HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)
<!-- 응답 -->
200 OK
Date: Tue, 15 Nov 1994 08:12:31 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/html
<HTML>
A page with an image
<IMG SRC="/myimage.gif">
</HTML>
HTTP/1.1 주요 내용
- HTTP WG에서는 HTTP/1.0 사양을 정리하는 동시에 좀 더 표준화된 사양인 HTTP/1.1 초안을 제작하고 있었고, 브라우저와 서버 개발자들은 제작 중인 초안을 참고하여 새 표준이 될 HTTP의 기능을 미리 구현해 놓았다. 그래서 HTTP/1.1의 경우, HTTP/1.0이 나온 지 얼마 지나지 않아서 나오게 되었다. (1996 -> 1997)
또한 HTTP/1.1의 제안 배경을 살펴보게 되면 아래와 같다.- HTTP/1.0 설계에서 불완전하고 미처 고려되지 못한 부분(계층적 프록시, 캐싱, 연결 지속 등)이 있어서 보완해야 함
- HTTP/1.0으로 통신한다고 선언해놓고 사양을 지키지 않은 서버와 클라이언트가 많다 보니 불편함
- Persistent Connection 추가
- 지정한 timemout 동안 커넥션을 닫지 않는 방법을 통해 커넥션의 사용성이 높아짐
- Pipelining 추가
- 앞 요청의 응답을 기다리지 않고 순차적인 여러 요청을 연속적으로 보내고 그 순서에 맞춰 응답을 받는 방식이 등장
- 순차적으로 하나씩 요청 / 응답이 처리되는 기존 방식을 개선
- 하나의 커넥션에 여러 개의 요청이 들어 있을 뿐, 동시에 여러개의 요청을 처리해 응답으로 보내주는 것은 아니다 (multiplexing 되지는 않음)
- 문제점❗
- Head Of Line Blocking (HOL)
: 결국 앞 요청의 응답이 너무 오래 걸리면 뒤 요청은 Blocking 되어버림 - Header 구조의 중복
: 연속된 요청의 헤더의 많은 중복이 발생
- Head Of Line Blocking (HOL)
HTTP/1.1 방식을 이용한 요청과 응답 예시.
/* 요청 */
GET /en-US/docs/Glossary/Simple_header HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header
/* 응답 */
200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 20 Jul 2016 10:55:30 GMT
Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
Keep-Alive: timeout=5, max=1000
Last-Modified: Tue, 19 Jul 2016 00:59:33 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding
(content)
HTTP/2.0 (2015년도에 등장)
기존 HTTP/1.x 버전의 성능 향상에 초점을 맞춘 프로토콜이며 기존 표준의 대체가 아닌 확장 개념.
변경점
- 메시지 전성 방식의 전환
- 일반 텍스트 형식(기존)
↓ - Binary Framing 계층을 추가해서 보내는 메시지를 프레임(frame)이라는 단위로 분할하며 추가적으로 바이너리로 인코딩을 한다
(바이너리 형식 사용으로 파싱속도 및 전송 속도가 빠르고 오류 발생 가능성이 낮아짐)
- 일반 텍스트 형식(기존)
- Multiplexed Streams
- 기존 : HTTP 1.1의 Pipelining으로 하나의 커넥션에 여러 요청이 있지만, 결국 동시에 여러 요청을 처리해 응답으로 주지는 못하였음
↓↓ - 구성된 연결 내에 전달되는 바이트의 양방향 흐름을 의미하는 Stream으로 요청 / 응답이 교환됨
(하나의 커넥션 안에 여러 개의 Stream 존재 가능) - 메시지가 이진화된 텍스트인 프레임(frame)으로 나뉘어 요청마다 구분되는 Stream을 통해 전달
- 즉, 프레임(frame)이 각 요청의 스트림(stream)을 통해 전달되며, 하나의 커넥션 안에 여러개의 스트림(stream)을 가질 수 있게 되어 다중화(multiplexing)가 가능해짐
-> 동시에 여러 요청을 처리하는 것이 가능해짐
-> Stream을 통해서 각 요청의 응답의 순서가 의미가 없어져서 HOL Blocking이 자연스럽게 해결됨
- 기존 : HTTP 1.1의 Pipelining으로 하나의 커넥션에 여러 요청이 있지만, 결국 동시에 여러 요청을 처리해 응답으로 주지는 못하였음
- Stream Prioritization
- 리소스 간 우선순위를 설정하는 기능
- Stream에 우선순위를 부여해서 인터리빙 되고 전달하는 것이 가능해짐
- Server Push
- 단일 클라이언트 요청에 여러 응답을 보낼 수 있는 특징을 통해 Server에서 client에게 필요한 추가적인 리소스를 push해주는 기능
- Header Compression
- 연속된 요청의 경우 많은 중복된 헤더의 전송으로 오버헤드가 많이 발생했음
↓↓ - 요청과 응답의 헤더 메타데이터를 압축해서 오버헤드를 감소
- 1) 전송되는 헤더 필드를 static dynamic table로 서버에서 유지
- 2) 이전에 표시된 헤더를 제외한 필드를 허프만(huffman) 인코딩을 수행해서 데이터를 압축
- 연속된 요청의 경우 많은 중복된 헤더의 전송으로 오버헤드가 많이 발생했음
QUIC / HTTP 3.0
- 등장 배경
- HTTP/2.0의 한계
- 각 요청마다 Stream으로 구분해서 병렬적으로 처리하지만, 결국 이에는 TCP 고유의 HOL Blocking이 존재
- 왜냐하면, 서로 다른 Stream이 전송되고 있을 때, 하나의 Stream에서 유실이 발생되거나 문제가 생기면 결국 다른 Stream도 문제가 해결될 때까지 지연되는 현상이 발생되기 때문
- 즉, 이러한 TCP의 태생적인 HOL Blocking을 해결하기 위해 QUIC / HTTP3.0이 등장
- QUIC?
- Google에서 개발한 UDP 기반의 전송 프로토콜 (Quick UDP Internet Connections)
- Google에서 TCP의 구조적 문제로 성능 향상이 어렵다고 판단하여 UDP 기반을 선택
- QUIC은 TCP의 3-way handshake과정을 최적화하는 것에 초점을 두고 개발됨.
- QUIC은 TCP의 Stream은 하나의 chain으로 연결되는 것과 다르게 각 Stream당 독립된 Stream chain을 구성하여 TCP HOL Blocking을 해결. HTTP 3.0
- QUIC을 기반으로 나온 새로운 HTTP 메이저 버전
⚡생각
HTTP에 대해서 나는 깊게 알고 있지 않았다. 웹을 개발하면서 Http Request , Http Response , POST, GET 등등을 많이 들어봤고, 대략적으로 프로토콜을 주고받는 것이다. 이 정도만 알고 있었다. 이번에 http를 정리하면서 여러 가지 자료를 많이 찾아봤으며, 깊게 알고 기억을 할 수 있으면 좋겠지만 나는 기억력이 좋은 편이 아니라서.... 이렇게 발전 과정을 보고 어떻게 사용되는지 다시 한번 되짚어 보면서 다시 한번 상기시키는 기회가 되었다.
'CS' 카테고리의 다른 글
[Git] git -f 명령어 위험성 공유 (0) | 2022.10.23 |
---|---|
네트워크에 대한 기본 개념 정리 (0) | 2022.10.12 |
HTTPS 개념 및 내용 정리 (0) | 2022.10.08 |
프로세스와 스레드에 대한 내용 정리 (0) | 2022.10.06 |
쿠키, 세션, 캐시에 대한 개념 정리 (0) | 2022.10.03 |