오늘의 나보다 성장한 내일의 나를 위해…












:pushpin: HTTP Connection


커넥션 관리는 HTTP의 주요 주제이다. 대규모로 커넥션을 열고 유지하는 것은 웹 사이트 혹은 웹 애플리케이션의 성능에 많은 영향을 준다. HTTP/1.x에는 몇 가지 모델이 존재한다.

  • 단기 커넥션
  • 영속적인 커넥션
  • 병렬 커넥션
  • HTTP 파이프라이닝


:pushpin: 단기 커넥션

HTTP 본래의 모델이자 HTTP/1.0의 기본 커넥션은 단기 커넥션이다. 각각의 HTTP 요청은 각각의 커넥션 상에서 실행된다. 이는 TCP 핸드 셰이크는 각 HTTP 요청 전에 발생하고, 이들이 직렬화됨을 의미한다.

TCP 핸드셰이크는 그 자체로 시간을 소모하기는 하지만 TCP 커넥션은 지속적으로 연결되었을 때 부하에 맞춰 더욱 예열되어 더욱 효율적으로 작동한다. 단기 커넥션들은 TCP의 이러한 효율적인 특성을 사용하지 않게 하며 예열되지 않은 새로운 연결을 통해 지속적으로 전송함으로써 성능이 최적 상태보다 저하된다.

이 모델은 HTTP/1.0에서 사용된 기본 모델이다. HTTP/1.1에서는 이 모델은 Connection 헤더가 close 값으로 설정되어 전송된 경우에만 사용된다.


영속적인 커넥션을 지원하지 않는 매우 낡은 시스템을 다루는 것이 아니라면 이 모델을 사용하려고 애쓸 필요가 없다


:pushpin: 영속적인 커넥션

단기 커넥션은 두가지 결점을 지니고 있다.

1) 새로운 연결을 맺는데 드는 시간이 상당하다
2) TCP 기반 커넥션의 성능은 오직 커넥션이 예열된 상태일 때만 나아진다는 것이다.


이런 문제를 완화시키기 위해 HTTP/1.1보다도 앞서 영속적인 커넥션의 컨셉이 만들어졌다. 이는 keep-alive 커넥션이라고 불리기도 한다.

영속적인 커넥션은 연결을 열어놓고 여러 요청에 재사용함으로써, 새로운 TCP 핸드셰이크를 하는 비용을 아끼고 TCP의 성능 향상 기능을 활용할 수 있다. 커넥션은 영원히 열려있지는 않으며 유휴 커넥션들은 얼마 후에 닫힌다.(서버는 Keep-Alive 헤더를 사용해서 연결이 최소한 얼마나 열려있어야 할지를 설정할 수 있다.)

물론 영속적인 커넥션도 단점을 가지고 있다. 유휴 상태일때에도 서버 리소스를 소비하며 과부하 상태에서는 DoS attacks을 당할 수 있다. 이런 경우에는 커넥션이 유휴 상태가 되자마자 닫히는 비영속적 커넥션(non-persistent connections)을 사용하는 것이 더 나은 성능을 보일 수 있다.

HTTP/1.0 커넥션은 기본적으로 영속적이지 않다. Connection를 close가 아닌 다른 것으로 일반적으로 retry-after로 설정하면 영속적으로 동작하게 될 것이다.

반면 HTTP/1.1에서는 기본적으로 영속적이며 헤더도 필요하지 않다.


:pushpin: 병렬 커넥션

HTTP는 클라이언트가 여러 개의 커넥션을 맺음으로써 여러 개의 HTTP 트랜잭션을 병렬로 처리할 수 있게 한다.

병렬 커넥션은 페이지를 더 빠르게 내려받는다. 하나의 커넥션으로 객체들을 로드할 때의 대역폭 제한과 대기시간을 줄일 수 있다면 더 빠르게 로드할 수 있다.

하지만, 병렬 커넥션이 항상 더 빠르지는 않다. 왜냐하면 클라이언트의 네트워크 대역폭이 좁을 때는 대부분 시간을 데이터 전송하는 데만 쓸 것이다. 그리고 다수의 커넥션은 메모리를 많이 소모하고 자체적인 성능 문제를 발생시킨다. 브라우저는 실제로 병렬 커넥션을 사용하긴 하지만 적은 수(대부분 4개, 최신 브라우저는 6~8개)의 병렬 커넥션만을 허용한다. 서버는 특정 클라이언트로부터 과도한 수의 커넥션이 맺어졌을 경우 그것을 임의로 끊어버릴 수 있다.

병렬 커넥션이 실제로 페이지를 더 빠르게 내려받는 것은 아니지만 화면에 여러 개의 객체가 동시에 보이면서 내려받고 있는 상황을 볼 수 있기 때문에 사용자는 더 빠르게 내려받고 있는 것 처럼 느낄 수 있다.


:pushpin: HTTP 파이프라이닝

기본적으로 HTTP 요청은 순차적이다. 현재의 요청에 대한 응답을 받고 나서야 다음 요청을 실시한다. 네트워크 지연과 대역폭 제한에 걸려 다음 요청을 보내는 데까지 상당한 딜레이가 발생할 수 있다.

파이프라이닝이란 같은 영속적인 커넥션을 통해서 응답을 기다리지 않고 요청을 연속적으로 보내는 기능이다. 이것은 커넥션의 지연을 회피하고자 하는 방법이다. 이론적으로는 두 개의 HTTP 요청을 하나의 TCP 메시지 안에 채워서 성능을 더 향상시킬 수 있다. HTTP 요청의 사이즈는 지속적으로 커져왔지만 일반적인 MSS(최대 세그먼트 크기)는 몇 개의 간단한 요청을 포함하기에는 충분히 여유 있다.

모든 종류의 HTTP의 요청이 파이프라인으로 처리될 수 있는 것은 아니다. GET, HEAD, PUT 그리고 DELETE 메서드 같은 idempotent 메서드만 가능하다. 실패가 발생한 경우에는 단순히 파이프라인 컨텐츠를 다시 반복하면 된다.

오늘 날, 모든 HTTP/1.1 호환 프록시와 서버들은 파이프라닝을 지원해야 하지만 실제로는 많은 프록시 서버들은 제한을 가지고 있다. 모던 브라우저가 이 기능을 기본적으로 활성화하지 않은 이유다.


:pushpin: HTTP란?


  • HTTP란 HyperText Transport Protocol의 약자로 웹서버와 클라이언트 간의 문서를 교환하기 위한 통신규약이다.
  • World Wide Web(WWW)의 분산되어 있는 Server와 Client 간에 Hypertext를 이용한 정보교환이 가능하도록 하는 통신 규약이다.
  • 1989년 Tim Berners Lee가 처음 설계
  • HTTP는 웹에서만 사용하는 Protocol로 TCP/IP 기반으로 한 지점에서 다른 지점(보통 클라이언트와 서버)으로 요청과 응답을 전송한다.


:pushpin: HTTP의 특징


  • HTTP 메시지는 HTTP ServerHTTP Client에 의해서 해석
  • TCP/IP 프로토콜Application 계층에 위치
  • TCP Protocol을 이용한다(Default Port 80)
  • 현재 Version 1.1 (RFC 2616)


:pushpin: HTTP 1.1


  • HTTP 1.0의 성능 개선에 중점을 두었다.


:pushpin: HTTP 1.0의 문제점

  • 단순한 OPEN, OPERATION, CLOSE
  • 매번 필요할 때마다 연결(비 지속성 연결방식) → 성능의 저하
  • 한번에 얻어서 가져올 수 있는 데이터 양이 제한
  • URL의 크기도 작으며, 캐시 기능이 미흡함(Last-Modified에 의존)
  • GET/HEAD/POST method만 허용


:pushpin: HTTP 1.1의 개선

  • 지속적인 연결을 해 주는 persistent connection 지원
  • multiple request 처리 가능
  • reqeust/responsepipeline 방식으로 진행
  • proxy server캐시 기능 향상(Cache-Control)
  • GET, HEAD, POST, OPTIONS, DELETE, TRACE, CONNECT 메소드 허용


:pushpin: 파이프라이닝(Pipe Lining) 이란?


  • 응답 메시지가 도착하지 않은 상태에서 연속적인 요구 메시지를 서버에 전달
  • 이때 서버는 요구 메시지를 수신한 순서대로 응답 메시지를 클라이언트에 전달
  • 연결과 종료횟수를 줄임으로서 네트워크 자원의 절약
  • 발생하는 패킷의 숫자를 감소, 네트워크 트래픽 감소




YoungKyonYou

Integration of Knowledge