Chillog 차가운 블로그

HTTP의 역사 - (2) HTTP/2.0과 QUIC의 등장

네트워크 웹의 역사

 이 포스트 역시 ‘마이크로서비스 아키텍처 구축’ 책읽기 포스트의 후속스터디 시리즈로, 이전 포스트 ‘HTTP의 역사 - (1) TCP/UDP 그리고 HTTP’에 이어 HTTP/2.0과 QUIC에 대한 내용을 다뤄본다. 각각 응용계층과 전송계층 스텍으로서 등장배경 위주로 정리해본다.


HTTP의 진화

  • HTTP 0.9 (1989)
  • HTTP 1.0 (1996)
  • HTTP 1.1 (1997) - 첫 표준
  • HTTP 2.0 (2015)
  • HTTP 3.0 (~Internet Draft)

첫 표준까지의 HTTP

 1991년에 HTTP가 출시됐다. 물론 정보문서로 공개된 날짜는 1996년 11월 RFC 1945이다. 정보공개된 버전인 HTTP 1.0과 구분짓기 위해 그 이전버전을 HTTP 0.9라고 부른다. 간단하게 정리된 특징으로는 다음과 같다. 자세한 내용은 Mozilar 문서에 잘 정리되어있다.

  • 0.9 버전은 오직 HTML 파일만이 송수신 가능함. 요청에 대한 단일라인으로 구성된 GET 메소드가 유일함.
  • 1.0 버전에 부족한 확장성을 보강하기위한 요청과 응답에 헤더가 추가됨. 송수신자의 메타데이터 확인가능해짐.
  • 1.0 버전에 Content-Type 추가됨. HTML이외에 다른 파일 전송할 수 있게 됨.

 HTTP는 릴리즈 이후 지속적으로 부족한 부분들을 지속적으로 보강해가며, 1995년도서부터는 표준화 작업도 같이 진행됐다. HTTP는 첫 번째 표준버전으로 1997년에 1.1 버전을 공개했다.

1. 영속적연결(Persistent Connections)과 파이프라이닝(Pipelining)

 당연히 HTTP는 TCP기반으로 만들어져있기에, 연결마다 전송계층(4계층)에서 TCP 3-Way/4-Way 핸드쉐이킹을 진행하고 데이터를 송수신한다. 1.0버전에서는 요청/응답때마다 핸드쉐이킹을 진행했었지만, 영속적연결의 등장으로 연결 재사용이 가능해지면서 잦은 요청에 따라 낭비되는 응답 시간과 네트워크 자원을 절약 할 수 있게되었다.

 또한 영속적연결과 함께 파이프라이닝이 추가됐다. 파이프라이닝은 요청에 대한 응답을 기다리지않고 다수의 요청을 보내는 기능을 말한다. 때문에 요청과 연결의 지연을 방지할 수 있다는 장점이 있다. 하지만 프록시에서 디버깅하기가 너무 어렵고 버그가 많았으며, 특히 Head-of-line Blocking 문제를 해결할 수 없어, 대부분의 경우는 성능 향상이 애매한 부분이 많았다. 때문에 파이프라이닝을 지원하지않는 프록시와 서버들이 많았고, 모던 브라우저에선 이 기능을 기본적으로 활성화하지 않고있다. 추후 HTTP 2.0에서는 ‘멀티플렉싱’ 알고리즘으로 대체된다.

연결에 따른 지연에 대한 문제는 해결했지만 HOLB과 같은 문제는 해결할 수 없었다.


2. 그외

 이외에도 HTTP의 특징관련해서는 중요한 내용들이 정말 많지만, 이 포스트에서는 키워드로 정리하는 선에서 마무리하겠다.

RESTful API
 2000년에는 HTTP의 새로운 사용 패턴에 대한 고안으로 RESTful API가 등장했다. 풀어서 얘기하면 REST한 API란 뜻이다. REST하다는 것은 ‘URI(Resource)와 HTTP Method(Verb)으로 표현된 것이 서버-클라이언트 환경아래 상태결과가 표현(Representation)된다’는 원칙이 지켜지며 설계되는 것을 말한다. 물론 각각의 웹사이트가 비표준으로 정의하고 사용할 수 있었기에 RESTful이라는 원칙이 잘 지켜지지 않는 경우가 많았다.
 그럼에도 불구하고 브라우저나 서버의 갱신없이 데이터 탐색과 수정을 허용하는 것은 큰 매력이었다. 확장성과 쓰임이 좋아 여러응용방법이 생겨났고, 어플리케이션들의 대표적인 인터페이스가 되어주었다. 간혹 오래된 문서들을 보다보면 종종 Resource-Oriented Architecture가 언급되는데, 출범당시 SOA와 대척점에 있던 아키텍처였었어서 썼던 용어인듯하다. 지금은 RESTful로 의미가 변·통합된 것으로 보인다.

API
 API는 Application Programming Interface, 즉 어플리케이션(프로그램)을 활용(프로그래밍)하기위해 외부로 노출되어있는 인터페이스를 말한다. 최근에는 ‘RestAPI=API’로 정리해도 무방할 것 같지만, ‘API’라는 용어는 OpenGL / DirectX와 같은 그래픽라이브러리나, WinAPI등이 같은 이름으로 아직 활용되고있기에 유의해서 사용하거나 읽을 필요는 있다.

SOAP API
 SOAP(Simple Object Access Protocol)은 SOA(Service Oriented Architecture) 패턴을 실현하기위한 프로토콜 기술이라고한다. SOA 패턴의 실패와 함께 자연스럽게 사라지고있다.

SSL과 TLS
 인증 및 데이터 암호화를 제공하는 프로토콜이다. 전송계층 위에 얹어 프로토콜을 구성한다. SSL (1995, Netscape) / TLS 1.0 (1999) SSL 3.0 기반 / TLS 1.1 (2006) / TLS 1.2버전(2008) / TLS 1.3(2018)


웹의 발전 그리고 서비스의 복잡화

 웹의 등장서부터 웹서비스들은 항상 발전해왔다. 복잡성과 병행하며 진보를 이뤘고, 그에 발맞춰 SOA와 같은 새로운 패턴의 도입을 시도하는 움직임이 있었다. 2000년대에 후반에 들어서자 사용자 환경, 특히 아이폰의 등장과 광대역 무선통신망의 보급으로 모바일 환경이 눈부시게 발전했으며, 그에 따라 화면에 보여지는 시각적 요소와 복잡한 상호작용 요소까지 점점 더 많이 추가되고있었다.

 발전된 환경은 서비스 공급자들이 제공할 수 있는 서비스의 종류가 많아지고 질이 매우 좋아졌음을 시사했지만, 반면에 서버로서는 더 많은 데이터와 더 많은 HTTP 리퀘스트를 처리해야했다. 좀 더 적은 네트워크 비용과 고가용성의 아키텍쳐가 필요했다. 구글을 중심으로 응용계층과 전송계층 스택 기술들을 개선해보려는 움직임이 일었다.


응용계층의 진화, SPDY 프로토콜과 HTTP 2.0의 등장

 그 많은 리퀘스트를 처리하기에는 HTTP/1.1의 리퀘스트 처리는 복잡하고 오버헤드를 일으켰으며, 무엇보다 변화된 서비스 환경에 쓰기엔 너무 오래됬었다. 2009년에 구글은 SPDY 프로토콜을 발표한다. ‘Speedy’로 발음하는 이 프로토콜은 ‘Make the Web Faster’ 라는 슬로건을 내세우며 제안한 프로토콜인데, 슬로건에서 볼 수 있듯이 웹페이지의 로드지연시간을 줄이는 것이 목표였다. 바이너리 프레이밍 계층을 도입하여, 요청/응답 다중화, 우선순위 지정 및 헤더 압축을 지원함으로써 기본 TCP 연결을 보다 효율적으로 사용 할 수 있게 했다. 이는 HTTP/1.x에 산재되어있던 문제점들을 해결해버렸고, 2012년에는 이미 구글의 자사 서비스 대부분을 SPDY로 제공하는 등 명실상부 차세대 프로토콜로서 각광을 받게된다. 같은해 11월에 HTTP/2.0 인터넷 드래프트가 SPDY를 기반하여 작성되게되면서 표준화 작업까지 진행하게된다.

 HTTP/2.0은 2015년 5월에 HTTP/2(RFC 7540)와 압축 알고리즘 HPACK(RFC 7541)가 함께 공개되면서 18년만의 HTTP의 새 버전 릴리즈가 이루어지게되었다. HOLB 문제를 해결했으며, 네트워크 리소스를 효율적으로 사용할 수 있게 되었다. HTTP/2의 주요 특징은 아래와 같다.

HTTP2.0의 주요특징 (접기/펼치기)

HTTP 2.0의 주요 특징

 1.1에서는 Plain Text를 주고 받았지만, 2.0에서는 메세지/프레임 단위를 Stream으로 주고 받는다는 것이 큰 변경점이다.

  • 바이너리 프레이밍(Binary Framing Layer): 클라-서버 소켓 인터페이스간의 새로운 인코딩 메커니즘을 구현한 계층임.
  • 헤더필드 압축(Header Compression): HPACK 알고리즘의 적용으로 중복되는 필드가 제거되고 헤더 데이터를 압축함. 데이터의 크기가 85~88% 감소됨.
  • 멀티플렉싱(Multiplexing): 동일한 연결에서 다중 동시 교환 허용함.
  • 흐름제어(Flow Control): 리소스 사용량을 제어함. TCP의 흐름제어와 비슷하나, 응용계층단에서 필요한 내용들이 구현되어있음.
  • 우선순위 지정 허용(Prioritization): 스트림에 종속성과 가중치를 부여하여 우선순위를 설정하는 기능임.
  • 서버푸쉬(Server Push): 특정 클라이언트 요청에 대해 여러 응답을 보낼 수 있는 기능임.

(Hypertext Transfer Protocol 버전 2, 초안 17)

'Header' 프레임과 'Data' 프레임으로 나뉘어 정보를 교환한다. 구글 개발자 레퍼런스

1. 용어정리: 스트림, 메시지, 프레임

  • 스트림(Stream): 연결된 연결에 대한 양방향의 bytes 흐름. 메시지(들)를 전송함.
  • 메시지(Message): 프레임의 완전한 하나의 시퀀스. 논리적 요청(Request)이나 응답(Response)에 매핑됨.
  • 프레임(Frame): HTTP/2의 통신 최소단위. 각 프레임에는 프레임 헤더가 포함되는데, 프레임이 속하는 스트림을 식별할 수 있는 최소한의 내용을 담고있음.

스트림에 기반하여 메시지를 주고받는다. 구글 개발자 레퍼런스

2. 개선된 점

  • HOLB 개선: 멀티플렉싱 알고리즘 적용으로, 파일을 병렬로 보낼 수 있게됨. 이는 HOLB 문제를 해결 할 수 있게함.
  • 페이지로드 시간 개선: 헤더압축으로 인하여 헤더필드 크기로인한 부담을 줄일 수 있게되고, 이는 페이지 로드 시간을 개선시킴.
  • 적은 TCP 연결: 서버푸쉬 기능으로 불필요한 요청을 줄일 수 있고, 특히 멀티플렉싱 덕에 단 하나의 TCP 연결만으로 병렬처리가 가능해짐.

멀티플렉싱으로 HOLB 문제를 해결했다. 구글 개발자 레퍼런스


전송계층의 진화, QUIC의 등장

 SPDY 프로토콜이 성공하고 HTTP 2.0의 기반기술로서 응용계층의 새 표준을 이끌무렵, 전송계층은 여전히 TCP가 주 프로토콜로 자리매김하고있었다. 지난 수년간 네트워크는 대역폭의 증가로 퍼포먼스를 비약적으로 증가시켜왔지만 이건 결국 ‘빛의 속도’에 제한될 운명이었다. 좀 더 좋은 네트워크 퍼포먼스를 내려면 결국에는 통신의 왕복횟수(Round-Trip Time)를 줄여야했었다. 그런의미에서 서너번의 RTT로 최대 일곱번까지 주고받는 TCP의 3/4-Way-Handshaking은 꽤 부담이었고, 이 RTT를 줄일려는 시도는 충분히 시도할만한 개선포인트였다. 2013년, Chromium 블로그에 ‘Experimenting with QUIC’라는 포스트가 올라온다. 바로 QUIC의 발표다.

 QUIC은 TLS에 UDP 기반인 Stream Multiplexing을 수행하는 네트워크 프로토콜로 만들었다며, RTT 횟수를 줄일 수 있는 기술들을 모아 정리했다고 설명했다.

'Zero RTT'. 정말 매력적인 개선이다. Chromium Blog

(작성중 …)

Quick UDP Internet Connection - QUIC

  • 구조
  • 보안
  • 속도

참조


2022 ⓒ ChillyMind