[Book - 그림으로 배우는 Http & Network Basic] 9. HTTP에 기능을 추가한 프로토콜
HTTP의 병목 현상을 해소하는 SPDY
HTTP의 병목 현상
SPDY(SPeeDY)는 HTTP의 병목 현상을 해소하고 웹 페이지 로딩 시간을 50% 단축한다는 목표로 개발되고 있다.
예를 들어 SNS에서 수백, 수천만 명의 유저가 메시지 등의 정보를 작성하면 웹 사이트에 그 정보들이 추가되면서 단시간에 대량의 갱신 정보가 발생하지만 HTTP에서는 이 처리를 제대로 할 수 없기 때문에 아래와 같은 HTTP의 사양이 병목 현상이 된다.
- 1개의 커넥션으로 1개의 Request만 보낼 수 있다.
- Request는 클라이언트에서만 시작할 수 있다. Response만 받는 것을 불가능하다.
- Request/Response 헤더를 압축하지 않은 체로 보낸다. 헤더의 정보가 많을수록 지연이 심해진다.
- 장황한 헤더를 보낸다. 매번 같은 헤더를 보내는 것은 낭비다.
- 데이터 압축을 임의로 선택할 수 있다. 압축해서 보내는 것이 강제적이지는 않는다.
Ajax에 의한 해결 방법
Ajax(Asynchronous JavaScript+XML)은 JavaScript나 DOM 조작 등을 활용하는 방식으로 웹 페이지의 일부분만 고쳐쓸 수 있는 비동기 통신 방법이다.
기존의 동기식 통신에 비해서 페이지의 일부분만 갱신되기 때문에 Response로 전송되는 데이터 양은 줄어든다는 장점이 있다.
핵심 기술은 XMLHttpRequest라는 API로 JavaScript 등의 스크립트 언어로 서버와 HTTP 통신을 할 수 있어서 이미 읽어 들인 웹 페이지부터 Request를 발행할 수 있기 때문에 페이지의 일부 데이터만 받는 것이 가능하게 된다.
Ajax는 실시간으로 서버에서 정보를 취득하려고 하면 대량의 Request가 발생한다는 문제가 있다.
HTTP의 프로토콜 자신이 가지고 있는 문제가 해결되는 것은 아니다.
Comet에 의한 해결 방법
Comet은 서버 측의 콘텐츠에 갱신이 있었을 경우 클라이언트부터 Reqeust를 기다리지 않고 클라이언트에 보내기 위한 방법이다.
보통 Request가 오면 Response를 바로 반환하지만 Comet에서는 Response를 보류 상태로 해 둠으로써 응답을 연장 시키고, 서버의 콘텐츠가 갱신 되었을 때에 Response를 반환한다. 따라서 서버에서 갱신된 콘텐츠가 있으면 바로 클라이언트에 반영할 수 있다.
콘텐츠를 실시간으로 갱신할 수는 있지만 Response를 보류하기 위해서 커넥션을 유지하는 시간이 길어진다. 즉, 커넥션을 유지하는 동안은 리소스를 소비한다.
HTTP 자체의 문제가 해결되는 것은 아니다.
SPDY의 목표
HTTP라는 프로토콜의 제약은 없앨 수는 없다.
근본적인 개선을 위해서는 프로토콜 레벨에서의 개선이 필요하다.
SPDY는 HTTP가 안고 있던 병목 현상을 프로토콜 레벨에서 해소하기 위해 개발이 진행되고 있는 프로토콜이다.
SPDY 설계와 기능
SPDY는 HTTP를 완전히 바꿔 놓는 것이 아니라 TCP/IP의 애플리케이션 계층과 트랜스포트 계층 사이에 새로운 세션 계층을 추가하는 형태로 동작한다.
또한, SPDY는 보안을 위해서 표준으로 SSL을 사용하도록 되어 있다.
SPDY을 사용하면 아래와 같은 기능을 HTTP에 추가할 수 있다.
다중화 스트림
단일 TCP 접속을 통해서 복수의 HTTP Reqeust를 무제한으로 처리할 수 있다.
한 번의 TCP 접속으로 Request를 주고 받는 것이 가능하기 때문에 TCP의 효율이 높아진다.
Request의 우선 순위 부여
SPDY는 무제한으로 Reqeust를 병렬 처리할 수 있지만 복수의 Request를 보낼 때 대역폭이 좁으면 처리가 늦어지는 현상을 해결하기 위해서 각 Request에 우선 순위를 할당할 수 있다.
HTTP 헤더 압축
Request와 Response의 HTTP 헤더를 압축함으로써 보다 적은 패킷 수와 송신 바이트 수로 통신할 수 있다.
서버 푸시 기능
서버에서 클라이언트로 데이터를 푸시하는 서버 푸시 기능을 지원해서 서버 측은 클라이언트 측에서 Request를 기다리지 않고 데이터를 보낼 수 있다.
서버 힌트 기능
서버가 클라이언트에게 Request해야 할 리소스를 제안할 수 있다.
클라이언트가 자원을 발견하기 전에 리소스의 존재를 알 수 있기 때문에 이미 캐시를 가지고 있는 상태라면 불필요한 Request를 보내지 않아도 된다.
SPDY는 웹의 병목 현상을 해결하는가?
SPDY는 기본적으로 한 개의 도메인(IP 주소)과의 통신을 다중화할 뿐이기 때문에 하나의 웹 사이트에서 복수의 도메인으로 리소스를 사용하고 있는 경우에는 그 효과는 한정적이게 된다.
SPDY는 HTTP의 병목 현상을 해결하는 좋은 기술이지만, 대부분 웹 사이트의 문제는 웹 자신을 고속화하기 위해 웹 콘텐츠 제작을 개선하는 등으로 HTTP의 병목 현상 때문만은 아니다.
브라우저에서 양방향 통신을 하는 WebSocket
Ajax와 Comet을 사용한 통신은 웹 브라우징을 고속화하지만 HTTP라는 프로토콜을 사용하고 있는 이상 병목 현상을 해결할 수 없다.
WebSocket은 새로운 프로토콜과 API에 의해 이 문제를 해결하기 위한 기술로 개발되어 있다.
WebSocket의 설계와 기능
WebSocket은 웹 브라우저와 웹 서버를 위한 양방향 통신 규격으로 WebSocket 프로토콜을 IETF가 책정하고 WebSocket API를 W3C가 책정하고 있다.
주로 Ajax나 Comet에서 사용하는 XMLHttpRequest의 결점을 해결하기 위한 기술로서 개발이 진행되고 있다.
WebSocket 프로토콜
WebSocket은 웹 서버와 클라이언트가 한번 접속을 확립하면 그 뒤의 통신을 모두 전용 프로토콜로 하는 방식으로 JSON이나 XML, HTML이나 이미지 등 임의 형식의 데이터를 보내게 된다.
HTTP에 의한 접속의 출발점이 클라이언트에 있다는 것에는 변함이 없지만 한 번 접속을 확립하면 WebSockeet을 사용하여 서버와 클라이언트 어느 쪽에서도 송신을 할 수 있게 된다.
WebSocket 프로토콜의 주요 특징
서버 푸시 기능
서버에서 클라이언트에 데이터를 푸시하는 서버 푸시 기능을 제공해서 서버는 클라이언트의 Request를 기다리지 않고 데이터를 보낼 수 있다.
통신량의 삭감
WebSocket은 접속을 한번 확립하면 접속을 유지하려고 한다. HTTP에 비해서 자주 접속을 하는 오버헤드가 적어지고, 또 헤더의 사이즈도 작기 때문에 통신량을 줄일 수 있다.
WebSocket으로 통신을 하려면 한번 HTTP에 접속을 확립하고, WebSocket에 의해 통신을 하기 위해서 핸드쉐이크(handshake) 절차를 밟을 필요가 있다.
핸드쉐이크 Request/Response
WebSocket API
JavaScript에서 WebSocket 프로토콜을 사용한 양방향 통신을 하기 위해서는 W3C에서 사양이 책정되어 제공되고 있는 WebSocket 인터페이스를 사용한다.
1 2 3 4 5 6 7 8 9 10
// WebSocket API를 사용해서 50ms에 1번 데이터를 송신하는 예 var socket = new WebSocket('{WebSockt API}'); socket.onopen = function() { setInterval(function() { if(socket.bufferedAmount == 0) { socket.send(getUpdateData()); } }, 50); };