minzzl
QUIC 프로토콜 이해 - 1장. HTTP 역사와 HTTP2 본문
안녕하세요, 최근 필자는 .. QUIC 프로토콜에 대한 연구를 진행 중입니다 ..
작년 부터 조금 씩 .. 진행해왔던 연구지만 다른 우선 순위들에 밀려 큰 진전은 없었던 터라 이렇게 블로그로 정리하며 가속도를 내볼까합니다.
하하
2017년 표준으로 인정받은 QUIC 프로토콜을 살펴보기에 앞서,
기존에는 어떤 프로토콜이 있었고, 또 어떤 과정으로 발전되어왔는지 살펴보겠습니다.
앞서 HTTP 라는 용어부터 봅시다.
Hyper Text Transform Protocol
네트워크 공부를 할 때 당연하게 접했던 하이퍼텍스트라는 용어는 소프트웨어 설계자이자 철학자인 넬슨이 1963년 즈음에 개념을 고안하여 1965년에 처음 발표한 것입니다. 그는 하이퍼텍스트의 개념을 다음과 같이 정의했습니다.
종이 위에서는 쉽게 표현할 수 없는 복잡한 방식으로 상호 연결된 글이나 그림 자료의 모음. 요약을 포함할 수 있고, 내용과 상호 관계의 지도를 포함 할 수도 있다/ 검토자들의 주석, 부연 설명, 각주를 포함할 수도 있다.
넬슨은 정보가 상호 연결되어 지워지지 않으면서 누구나 쉽게 사용할 수 있는 문서우주를 만들기를 원했다고 합니다. 그의 하이퍼텍스트 시스템 프로젝트는 빛을 보지는 못하였지만 후대에 지대한 영향을 끼칩니다.
HTTP는 1989년에 처음 등장했습니다. CERN에서 일하던 팀 버너스 리는 연구소에서 가속기와 각종 실험을 통해 얻은 정보를 관리하는 데 도움을 주는 새 시스템을 제안했습니다. 그는 넬슨이 주창한 개념 두 가지를 채택했는데, 첫째는 "제약 없는 방식으로 서로 연결되어 사람이 읽을 수 있는 정보"를 의미하는 하이퍼텍스트며, 둘째는 "정보가 반드시 텍스트 형태일 필요는 없다"는 하이퍼미디어입니다.
그는 수 많은 기계에서 서버와 브라우저를 구동해 "범 세계적인 시스템을 제공하고자 제안했습니다"
HTTP란 HTML 문서와 갗은 리소스들을 가져올 수 있도록 해주는 프로토콜입니다.
HTTP는 거듭하여 진화해온 확장 가능한 프로토콜입니다. HTTP는 애플리케이션 계층의 프로토콜로, 대부분 TCP 혹은 암호화된 TCP 연결인 TLS를 통해 전송됩니다. 최근에는 UDP를 통한 전송이 이루어지기도 하는데요, 이것이 QUIC과 맞닿아있는 내용입니다. 이 부분에 대해서는 차차 알아가도록 하겠습니다.
사실, 서두가 좀 길었던 것 같습니다...
^^
본론 이었던 HTTP의 역사에 대해 알아보겠습니다.
HTTP 의 역사를 간단히 나타내어보면 아래와 같습니다.
그렇다면 각 버전 별로 어떤 특징이 있었는지 살펴보겠습니다.
HTTP/0.9 - 원라인 프로토콜
1989년 제네바의 CERN에서 일하고 있던 팀 버너스 리는 인터넷의 하이퍼텍스트 시스템을 만들기 위한 제안을 하였습니다. 앞서 이야기한 "범 세계적인 시스템을 제공하고자 제안"한 프로젝트입니다. 이렇게 HTML, HTTP, WorldWideWeb, httpd의 초기 버전이 1990년 말에 완료되었고 첫번째 서버는 1991년 초에 CERN 외부에서 가동을 시작하게 됩니다.
이후 몇 년간, HTTP의 사용이 계속 증가했습니다. 1995년에는 80번 포트에서 HTTP 트래픽을 처리하는 서버가 전 세계적으로 18,000대를 넘어 설 정도로 말이죠..
사실 HTTP/0.9는 매우 단순한 프로토콜이었습니다. 단 하나의 메서드(GET)만 있었고, 어떠한 헤더도 없었으며, 이미지는 처리 할 수 없고 텍스트만 다룰 수 있는 HTML만 가져오도록 설계되었습니다.
초기에는 버전 정보가 존재하지 않았지만, 이후에 다른 버전들과 구분하기 위해서 0.9라는 버전을 붙이게 되었다고 합니다. 0.9 버전은 단일 라인으로 구성 되었으며 path는 GET이 유일했습니다. 이렇게 제한적인 기능을 갖고 있었던 HTTP/0.9는 다음과 같은 특징을 갖고 있습니다.
- 클라이언트-서버, 요청-응답 프로토콜
- TCP/IP 링크를 통해 실행되는 ASCII 프로토콜
- 하이퍼 텍스트 문서(HTML)을 전송하도록 설계
- 서버와 클라이언트 간의 연결은 모든 요청 후에 닫힘
$> telnet google.com 80
Connected to 74.125.xxx.xxx
GET /about/
(hypertext response)
(connection closed)
요청은 GET 메소드와 요청하는 문서의 패스로 구성되어 한줄로 이루어져있습니다.
그에 대한 응답은 단일한 하이퍼텍스트 문서로 헤더도 없고, 다른 메타데이터도 없고, HTML만 가집니다. 이러한 프로토타입은 요구사항 기능들의 일부를 구현했기에 비공식적으로 HTTP 0.9 라벨이 붙게되었습니다.
HTTP/1.0 - HTTP의 성장
최초의 인기 브라우저 Mosaic가 탄생하고, 1994년 Netscape Navigator 1.0이 출시되면서 인터넷의 성장은 날이 갈 수록 거대해졌습니다. 같은 해 W3C가 만들어지며 HTML의 발전을 도모하게 되었고, 이와 비슷하게 HTTP 프로토콜 개선에 초점을 맞추기 위해 HTTP-WG가 설립되었습니다. 마지막으로 1994년~1995 기간에 전화 접속 인터넷 엑세스가 제공되기 시작하며 인터넷의 붐이 도래했습니다.
이러한 성장을 통해 1996년 5월 HTTP-WG는 HTTP/1.0 구현의 일반적인 사용을 문서화한 RFC 1945를 발표하였습니다.
이는 다음과 같은 요청과 응답 포맷으로 구성되었습니다.
// 요청 + 헤더
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>
1/0 버전은 이전 0.9 버전에 비해 어마어마한 변화를 가져왔다고 합니다. 0.9 버전의 규격은 한페이지 정도였지만, 1.0 버전은 60 페이지에 달했을 정도였다고 하니, 다양한 개념들이 이 당시에 도입되었다고 할 수 있습니다.
오늘날 매우 친숙한 헤더, 응답코드, 리다이렉트, 오류, 조건부 요청, 콘텐츠 인코딩(압축), 더 다양한 요청 메소드 등입니다.
이렇게 발표된 HTTP/1.0의 특징은 다음과 같습니다.
- 버전 정보가 각 요청 사이내로 전송되기 시작합니다.
- 상태 코드 라인 또한 응답의 시작 부분에 전송되어, 브라우저가 요청에 대한 성공과 실패를 알 수 있고 그 결과에 대한 동작을 할 수 있게 되었습니다. 이 때 그 결과에 대한 동작은 특정 방법으로 그것을 로컬 캐시를 갱신하거나 사용하는 것을 예로 들 수 있습니다.
- HTTP 헤더 개념은 요청과 응답 모두를 위해 도입되어, 메타데이터 전송을 허용하고 프로토콜을 극도로 유연하고 확장 가능하도록 만들어주었습니다.
- 새로운 HTTP 헤더의 도움으로, 평이한 HTML 파일들 외에 다른 문서들을 전송하는 기능이 추가되었습니다.(Content-Type을 통해서,,)
0.9에 비해 비약적으로 개선된 것은 사실입니다. 그러나 HTTP/1.0에도 해결해야할 결함들이 많이 존재했습니다. 여러 요청 사이에 연결을 유지하는 기능은 없었으며 Host의 헤더는 필수가 아니었습니다. 또한 캐싱 옵션은 매우 빈약했습니다. 이 세 항목은 향후 웹의 발전에 큰 영향을 미치는 부분이었기에, 반드시 해결해야만 하는 것이었습니다.
HTTP/1.1 - HTTP의 표준
1995년부터 다양한 HTTP/1.0 구현이 동시에 진행되었고, 몇달 뒤 1997년 초에 HTTP/1.1이 발표되었습니다. 그 후 2년 반 후인 1999년 6월 여러 개선 사항과 업데이트가 표준에 통합되어 RFC 2616으로 출시되었습니다. 이 프로토콜은 지금까지 20년 넘게 명맥을 유지해오고 있습니다. 1.1 버전에서는 앞서 언급한 많은 문제점이 고쳐졌습니다. Host 헤더를 필수 항목으로 지정한 덕분에 가장 호스팅, 즉 하나의 IP 주소로 다수의 웹 프로퍼티를 제공할 수 있게 되었습니다. 새 연결 지시자를 사용하면 웹 서버는 응답 후에 연결을 끊을 필요가 없었으며, 브라우저는 모든 요청 마다 TCP 연결을 재 수립 할 필요도 없었기에 성능과 효율이 대폭 개선되었습니다.
HTTP / 1.1 표준은 이전 버전에서 발견 된 더 많은 프로토콜 모호성을 해결하고 keep-alive 연결, chunk encoding 전송, 바이트 범위 요청, 추가 캐싱 메커니즘, 전송 인코딩 및 요청 파이프 라이닝과 같은 여러 중요한 성능 최적화를 도입했습니다.
좀 더 보완된 특징은 다음과 같습니다.
- 커넥션이 재사용될 수 있게 하여, 탐색된 단일 원본 문서 내로 임베드된 리소스들을 디스플레이 하기 위해 사용된 커넥션을 다시 열어 시간을 절약합니다.
- 파이프라이닝을 추가하여, 첫번째 요청에 대한 응답이 완전히 전송되기 이전에 두번째 요청 전송을 가능케하여, 커뮤니케이션 레이턴시를 낮추었습니다.
- 청크된 응답 또한 지원됩니다.
- 추가적인 캐시 제어 매커니즘이 도입되었습니다.
- 언어, 인코딩 혹은 타입을 포함한 컨텐프 협상이 도입되어, 클라이언트와 서버로 하여금 교환하려는 가장 적합한 컨텍츠에 대한 동의를 가능케하였습니다.
- Host 헤더 덕분에, 동일 IP 주소에 다른 도메인을 호스트하는 기능이 서버 코로케이션을 가능케합니다.
여기서 파이프라이닝은 클라이언트가 모든 요청을 동시에 전송할 수 있는 기능입니다. 하지만 파이프라이닝은 몇 가지 문제점이 있어 잘 사용되지는 않습니다. 서버는 요청을 동시에 받더라도 여전히 순서대로 응답을 해야합니다. 이는 어떤 한 요청을 처리하는 데 시간이 오래 걸리는 경우, HOL 블로킹 현상으로 인해 다른 요청들에 대한 응답도 함께 지연됨을 의미합니다. 게다가 인터넷 상의 서버와 프락시 중 파이프라이닝을 제대로 구현한 곳은 거의 없으며, 있더라도 제대로 동작하지 않는 경우가 많다고합니다.
아래는 하나의 단일 커넥션을 통한 요청의 전형적인 전체 흐름의 예시입니다.
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)
GET /static/img/header-background.png 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: */*
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
Age: 9578461
Cache-Control: public, max-age=315360000
Connection: keep-alive
Content-Length: 3077
Content-Type: image/png
Date: Thu, 31 Mar 2016 13:34:46 GMT
Last-Modified: Wed, 21 Oct 2015 18:27:50 GMT
Server: Apache
(image content of 3077 bytes)
이후 2014년 RFC 7230, 7231, 7232, 7233, 7234, 7235 버전으로 업데이트가 되었습니다.
SPDY 와 이를 기반으로 한 HTTP/2 의 등장
사실 HTTP/1.1이 1999년에 발표난 후, 논쟁의 여지 없이 인터넷에서 가장 인기 있는 애플리케이션 프로토콜이었습니다. 그러나 HTTP는 그 나이를 체감해야만 했습니다..
이제는 웹 페이지를 불러오려면 수백 번의 요청을 해야만 했고, 그로 인해 누적된 오버헤드가 웹을 느리게했습니다.
그 해결책을 찾기 위한 웹 성능 최적화라는 영역이 자생하기 시작했습니다.
SPDY는 Google에서 개발한 시험용 프로토콜이며 2009년 중반에 발표되었습니다. HTTP/2의 주요 목표는 전체 요청을 통해 지연 시간을 줄이고, 응답을 다중화를 지원하며, HTTP 헤더 필드의 효율적 압축을 통해 프로토콜 오버헤드를 최소화, 요청 우선 순위 지정을 추가, 서버 푸시를 지원하는 것이었습니다.
지금까지 우리는 SPDY를 실험실 조건에서만 테스트했습니다. 초기 결과는 매우 고무적이었습니다. 시뮬레이션된 홈 네트워크 연결에서 상위 25개 웹사이트를 다운로드할 때, 성능이 상당히 개선되었으며 페이지가 최대 55% 더 빨리 로드되었습니다. (Chromium 블로그)
이러한 성능 향상에 힘입어 SPDY를 사용하는 사이트가 늘어나게 되었고 사실상의 표준이 되었습니다. 이러한 상황을 주시하고 있던 HTTP-WG는 HTTP/2 표준을 선보이려는 노력을 했고 이 프로토콜의 출발점을 SPDY 사양을 채택하게 됩니다.
이렇게 2012년 부터 2015년까지 3년간의 노력으로 HTTP/2 표준이 발행되게 되었습니다. 그렇게 몇년간 함께 발전해 온 SPDY는 지원을 중단하였고, HTTP2가 널리 채택된다는 말을 남기고 사라지게 됩니다.
HTTP2와 HTTP1의 차이점은 아래와 같습니다.
- 바이너리 프레이밍 계층
- 스트림, 메시지 및 프레임
- 요청 및 응답 다중화
- 스트림 우선순위 지정
- 출처 당 하나의 연결
- 흐름제어
- 서버 푸쉬
- 헤더 압축
* 다음의 글을 참고하여 작성하였습니다.
https://kyun2da.dev/CS/http%EC%9D%98-%EC%97%AD%EC%82%AC%EC%99%80-http2%EC%9D%98-%EB%93%B1%EC%9E%A5/
- 러닝 HTTP/2 : 핵심만 쏙쏙, HTTP/2 적용 실무 가이드
'논문 > QUIC' 카테고리의 다른 글
[Congestion control] -혼잡제어에 대한 소개 (2) | 2023.02.23 |
---|---|
TCP의 window based Flow Contorl (흐름제어) (0) | 2023.02.21 |
리눅스 tc 명령어 사용법 (0) | 2023.02.19 |
QUIC 프로토콜 이해 - 2장. 웹을 파헤치는 이유와 방법 (0) | 2022.12.19 |