[HTTP_NETWORK] HTTP기반의 프로토콜

업데이트:

HTTP 규격이 처음 만들어졌을떄는 주로 HTML로 작성된 문서를 전송하기 위한 프로토콜로 HTTP를 생각했다. 그러나 세월이 지나면서 웹의 용도는 변화하고 있다. 웹 애플리케이션이나 스등을 구사해서 그들이 원하는 기능을 만들 수는 있지만 그것이 효율적이라고 할 수는 없다. HTTP라는 프로토콜의 제한이나 한계가 있기 때문이다.

HTTP의 기능이 부족하면 새로운 프로토콜을 만들면 되지 않을까? 이미 웹 브라우저라는 환경이 널리 사용되는 지금 HTTP라는 프로토콜을 무시할수는 없다. 그래서 HTTP를 기반으로 해서 여기에 추가하는 형태로 새로운 프로토콜이 몇 가지가 구현되고 있다.

이번 시간에는 HTTP 기반의 프로토콜들에 대해 알아보자.


1. HTTP의 병목 현상을 해소하는 SPDY

Google이 2010년 발표한 SPDY는 HTTP의 병목현상을 해소하고 웹 페이지 로딩 시간을 50% 단축한다는 목표를 세우고 개발했었다. 하지만 HTTP/2.0에 의해 크롬에서도 SPDY 지원이 중단된 상태이다.

페이스북이나 트위터 등의 SNS는 많은 사람들이 작성한 정보를 실시간으로 보여준다. 수백만명, 수천만명의 유저가 정보를 작성하면 웹 사이트에 정보가 추가되면서 단시간에 대량의 정보가 발생한다. 이렇게 갱신된 정보를 실시간으로 표시하기 위해서는 서버상의 정보가 갱신되었을 때, 그것을 클라이언트의 화면에 반영할 필요가 있다. 단순하게 보일 수 있지만 HTTP에서는 이 처리를 제대로 할 수가 없다.

HTTP에서는 서버의 정보가 갱신되었는지 알기 위해 클라이언트가 서버에 확인하러 가야 한다. 만약 서버의 정보가 갱신되지 않았다면 불필요한 통신이 발생한다. HTTP 사양에서는 다음과 같이 처리할수밖에 없다.

  • 1개의 커넥션으로 1개의 리퀘스트만 보낼 수 있다
  • 리퀘스트는 클라이언트에서만 시작할 수 있다
  • 리퀘스트/리스폰스 헤더를 압축하지 않은 채로 보낸다. 헤더의 정보가 많을수록 지연이 심해진다
  • 장황한 헤더를 보낸다. 매번 같은 헤더를 보내는 것은 낭비이다
  • 데이터 압축을 임의로 선택할 수 있다. 압축하는것이 강제가 아니다
1) Ajax에 의한 해결법

Ajax는 JavaScript나 DOM 조작 등을 활용하는 방식으로 웹 페이즈의 일부만 새로 불러오는 비동기 통신 방법이다. 기존의 통신에 비해 일부만 갱신되기 때문에 리스폰스로 전송되는 데이터 양이 줄어든다는 장점이 있다. Ajax의 핵심 기술은 XMLHttpRequest라는 API로 JavaScript 등의 스크립트 언어로 서버와 HTTP 통신을 할 수 있다. 이것을 사용함으로써 이미 읽어들인 웹 페이지에서 리퀘스트를 발행할 수 있기 때문에 페이지의 일부 데이터만 받는 것이 가능하게 된다.

Ajax를 사용해 실시간으로 서버에서 정보를 취득하려 하면 대량의 리퀘스트가 발생한다는 문제가 있다. 또 HTTP 프로토콜 자체가 가지고 있는 문제가 해결되는 것은 아니다.

2) Comet에 의한 해결법

Comet은 서버 측의 콘텐츠 갱신이 있는 경우 클라이언트의 리퀘스트를 기다리지 않고 클라이언트에 리스폰스를 보내기 위한 방법이다. 일반적으로 리퀘스트가 오면 리스폰스를 바로 반환하지만 Comet에서는 리스폰스는 보류 상태로 두고 서버의 콘텐츠가 갱신되었을 때 리스폰스를 반환한다. 이를 통해 서버에 갱신된 콘텐츠가 있으면 바로 클라이언트에 반영할 수 있다.

콘텐츠를 실시간으로 갱신할 수 있지만 리스폰스를 보류하기 위해 커넥션을 유지하는 시간이 길어진다. 이 시간에 리소스를 소비하기도 하고, HTTP 프로토콜 자체가 가지고 있는 문제가 해결되는 것은 아니다.

SPDY의 기능

SPDY의 기능을 사용하면 다음의 기능을 HTTP에 추가할 수 있다

  • 다중화스트림 : 단일 TCP 접속을 통해 복수의 HTTP 리퀘스트를 무제한으로 처리할 수 있다. 한 번의 접속으로 리퀘스트를 주고받는 것이 가능하기 때문에 TCP의 효율이 높아진다.
  • 리퀘스트의 우선순위 부여 : 무제한의 리퀘스트를 병렬 처리할 수 있지만, 우선순위를 할당할 수 있다. 이는 복수의 리퀘스트를 보낼 때 대역폭이 좁으면 처리가 늦어지는 현상을 해결하기 위함이다.
  • HTTP 헤더 압축 : 리퀘스트와 리스폰스의 HTTP 헤더를 압축하여 적은 패킷 수와 송신 바이트 수로 통신을 할 수 있다.
  • 서버 푸시 기능 : 서버에서 클라이언트로 데이터를 푸시하는 기능. 리퀘스트 없이 서버에서 데이터를 보낼 수 있다.
  • 서버 힌트 기능 : 서버가 클라이언트에 리퀘스트 해야 할 리소스를 제안할 수 있다. 클라이언트가 리소스의 존재를 알 수 있기 떄문에 이미 캐시된 경우 리퀘스트를 보내지 않아도 된다.

2. 양방향 통신을 가능하게 하는 WebSocket

Ajax와 Comet을 사용한 통신은 웹 브라우징을 고속화하지만 HTTP라는 프로토콜을 사용하는 이상 병목 현상을 해결할 수는 없다. WebSocket은 새로운 프로토콜과 API에 의해 이러한 문제를 해결하기 위한 기술로 개발되었다.

WebSocket은 웹 서버와 클라이언트가 한 번 접속을 확립하면 그 뒤의 통신을 모두 전용 프로토콜로 하는 방식으로 Json이나 XML, HTML이나 이미지 등 임의 형식의 데이터를 보내게 된다. HTTP에 의한 연결의 시작이 클라이언트에 있다는 것은 변함이 없지만 한 번 접속을 확립하면 WebSocket을 사용해 서버와 클라이언트 어느 쪽에서도 송신을 할 수 있게 된다. 주요 특징은 다음과 같다.

  • 서버 푸시 기능 : 서버에서 클라이언트에 데이터 푸시 가능. 리퀘스트 없이 데이터를 보낼 수 있다.
  • 통신량의 삭감 : WebSocket은 접속을 한 번 확립하면 접속을 유지하려 한다. HTTP에 비해 자주 접속을 하는 오버헤드가 적어지고 헤더 사이즈도 작아져 통신량을 줄일 수 있다. WebSocket으로 통신을 하려면 한 번 HTTP에 접속을 확립하고 WebSocket에 의한 통신을 하기 위해 handshake 절차를 밟을 필요가 있다
  • handshake/Request : WebSocket 통신을 하려면 HTTP의 Upgrade 헤더 필드를 사용해 프로토콜을 변경하는 것으로 핸드쉐이크를 실시한다. Sec-WebSocket-Key에는 핸드쉐이크에 필요한 키가 저장된다.
Upgrade: WebSocket
Sec-WebSocket-Key: dqWIJGiwjgliJWEo==
  • handshake/Responset : handshake/Request에 대한 리스폰스는 상태코드 101 Switching Protocols 로 반환된다. Sec-WebSocket-Accept는 Sec-WebSocket-Key의 값에 의해 생성된 값이 저장된다. 핸드쉐이크 이후 WebSocket 커넥션이 확립된 후에는 HTTP가 아닌 WebSocket 프레임을 통해 통신을 한다.
Sec-WebSocket-Accept: s3ghierogSAJFlweg=
WebSocket API

JavaScript에서 WebSocket 프로토콜을 사용하기 이해서는 W3C에 사양이 책정되어 제공되는 WebSocket 인터페이스를 사용한다. 다음은 WebSocket API를 사용해 50ms에 1번 데이터를 송신하는 예이다.

var socket = new WebSocket('ws://1q1w.github.io');
socket.onopen = function(){
	setInterval(function(){
		if(socket.bufferedAmount == 0){
			socket.send(getUpdateData());
		}
	}, 50);
}

3. HTTP/2.0

SPDY나 WebSocket이 등장에서 보듯 HTTP/1.1은 웹에 적합한 프로토콜이라 할 수 없다. HTTP/2.0은 웹 이용시 체감 속도 개선을 목표로 개발되었다. 이는 SPDY와 WebSocket을 베이스로 개발이 되었다고 볼 수 있다. HTTP/2.0은 SPDY의 특징이라고 앞에서 소개한 기능들이 가능한 프로토콜이다. 특징은 다음과 같다.

  • Multiplexed Streams : 한 커넥션으로 동시에 여러개의 메세지를 주고 받을 있다.

  • Stream Prioritization : 리퀘스트의 우선순위를 부여할 수 있다.

  • Server Push : 서버는 클라이언트의 요청에 대해 요청하지도 않은 리소스를 마음대로 보내줄 수 있다. 예를 들어 HTML을 문서를 클라이언트가 요청하였는데 여기에 여러개의 리소스(css, 이미지 등)이 포함된 경우 HTTP/1.1은 이러한 이미지를 재요청 하는 반면 HTTP/2.0은 클라이언트가 요청하지 않아도 알아서 보내준다. 이를 PUSH_PROMISE라 부른다.

  • 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 기법으로 인코딩 처리 하여 전송한다.

4. 웹 서버 상의 파일을 관리하는 WebDAV

WebDAV는 웹 서버의 콘텐츠에 대해 직접 파일 복사나 편집 등을 할 수 있는 분산 파일 시스템으로 HTTP/1.1을 확장한 프로토콜로 RFC4918로 정의되어 있다. 파일작성, 삭제 등 기본기능 이외에 파일 작성자 등의 관리나 편집중 다른 유저가 다시 고쳐쓰지 못하도록 하는 잠금 기능, 갱신 정보를 관리하는 리비전 기능 등이 있다. HTTP/1.1의 PUT, DELETE 메소드를 사용하면 웹 서버 상의 파일 작성이나 삭제를 할 수 있지만 보안이나 편의성 등의 문제가 있어 사용되지는 않고 있다.

WebDAV에는 다음과 같은 개념이 있다.

  • Collection : 여러 개의 리소스를 한꺼번에 관리하기 위한 개념이다. 각종 조작은 Collection 단위로 할 수 있다. Collection 속에 Collection을 두어 사용할 수도 있다
  • Resource : 파일이나 Collection을 Resource라 부른다
  • Property : Resource의 Property를 정의한 것이다. 정의는 ‘이름 = 값’ 의 형식으로 이루어진다
  • Lock : 파일을 편집할 수 없는 상태로 한다. 여러 사람이 동시에 편집하는 경우 등을 예방한다.

WebDAV에서는 리모트 파일 관리를 위해 HTTP/1.1에 다음과 같은 메소드를 추가했다.

  • PROPFIND : 프로퍼티 취득
  • PROPPATCH : 프로퍼티 변경
  • MKCOL : 컬렉션 작성
  • COPY : 리소스 및 프로퍼티 복제
  • MOVE : 리소스 이동
  • LOCK : 리소스 잠금
  • UNLOCK : 리소스 잠금 해제

메소드 확장에 따라 상태 코드도 확장되었다.

  • 102 Processing : 리퀘스트는 정상수신되었지만 아직 처리중이다
  • 207 Multi-Status : 복수의 스테이터스를 가지고 있다
  • 422 Unprocessable ENtity : 서식은 올바르지만 내용이 틀리다
  • 423 Locked : 리소스가 잠겨있다
  • 424 Failed Dependency : 어떤 리퀘스트에 관련된 리퀘스트가 실패하여 의존 관계를 유지하지 못한다
  • 507 Insufficient Storage : 저장소가 불충분하다

왜 이렇게까지 HTTP가 사용될까?

과거 네트워크를 이용한 시스템이나 소프트웨어를 만드는 경우 필요한 기능을 구현한 새로운 프로토콜을 만드는 경우가 있었으나 최근에는 HTTP를 사용하는 쪽이 대부분이다. 많은 이유 중의 하나로 기업이나 조직의 방화벽 설정과 크게 관련이 있다. 방화벽의 기본 기능 중 지정된 프로토콜이나 포트 번호 이외의 패킷은 통과시키지 않는다는 기능이 있어 이로 인해 새로운 프로토콜이나 포트 번호를 이용하는 경우 설정을 변경할 필요가 생긴다. 인터넷에서 가장 많이 활용되는 분야는 웹이다.

웹은 HTTP에서 동작하기 떄문에 웹 서버를 구축하거나 액세스를 위해 방화벽 설정에서 HTTP(80/tcp)나 HTTPS(433/tcp)를 허가해둘 필요가 있다. 따라서 HTTP는 많은 회사나 조직에서 허가된 통신 환경인 경우가 많아 방화벽 설정을 변경할 필요 없이 도입이 용이하다는 장점이 있다. 이것이 HTTP 기반의 서비스와 콘텐츠가 늘어나는 이유 중 하나이다. 다른 이유로는 HTTP 클라이언트인 브라우저가 보급되어있는 것이나 HTTP 서버가 많이 보급되었다는 이유도 있는 것 같다.