pungjoo

HTTP 1.1 Keep-Alive 기능에 대해 본문

HTTP

HTTP 1.1 Keep-Alive 기능에 대해

pungjoo.kim 2008.01.15 00:20

들어 가면서
HTTP는 아시다 시피 connection less 방식으로 연결을 매번 끊고 새로 생성하는 구조입니다. 이는 network 비용측면에서 많은 비용을 소비하는 구조입니다.( 최초 연결하기 위한 준비과정을 의미함 ) 그래서 HTTP 1.1부터는 Keep-Alive라는 기능을 지원합니다.

Keep Alive란?
Keep Alive란 연결된 socket에 IN/OUT의 access가 마지막으로 종료된 시점부터 정의된 시간까지 access가 없더라도 대기하는 구조입니다. 즉 정의된 시간내에 access가 이루어진다면 계속 연결된 상태를 유지할 수 있다는 것 이죠.

HTTP 下에서 Keep Alive란?
HTTP는 앞서 설명드린 것과 같이 connection less방식이라 매번 socket(port)를 열어야 하고 이는 비용적인 측면에서 비효율적인 구조입니다. 해서 keep Alive time out내에 client에서 request를 재 요청하면 socket(port)를 새로 여는 것이 아니라 이미 열려 있는 socket(port)에 전송하는 구조가 됩니다.

예를 들면 image를 4개를 보여주는 구조에서 client는 동시에 2개의 image만 얻어 올수 있고 1개의 image는 얻는데 2초 걸리고 port를 여는데 1초가 걸린다고 가정.

  1. keep alive : false
    처음 server에 2개의 port를 열고 image를 얻고 client socket의 닫고 ( 3초 )
    다시 server에 2개의 port를 열고 image를 얻고 client socket을 닫음 ( 3초 )
    총 6초가 걸림.
  2. keep alive : true
    처음 server에 2개의 port를 열고 image를 얻고 ( 3초 )
    다시 첫번째 요청에서 열어 둔 2개의 port에 2개의 image를 얻음 ( 2초 )
    keep alive time out이 되었을 때 client의 socet이 닫히거나 browser가 더 이상 얻어 올 것이 없으면 자동으로 닫어 버림.
    총 5초가 걸림.


Keep Alive를 그럼 어떻게 쓸수 있는가?
딱, 잘라서 말하면 개발자 영역에서 할 부분은 전혀 없습니다.

  1. client(browser)는 http 1.1을 준수하고 이해 할수 있다고 request에 Connection: Keep-Alive를 넣어서 Server에 전송
    즉 client는 http 1.1 spec을 구현하고..
  2. server도 http 1.1 spec을 구현하고 keep alive 기능을 활성화하고 keep alive time out을 설정

참고
client에서 keep alive code를 보내고 server도 kepp alive 기능을 제공할 경우.

$ telnet pungjoo.com 80
Trying 121.124.124.74...
Connected to pungjoo.com.
Escape character is '^]'.
GET / HTTP/1.1
Host: pungjoo.com
Connection: Keep-Alive

HTTP/1.1 302 Moved Temporarily
Date: Tue, 15 Jan 2008 01:32:45 GMT
Set-Cookie: JSESSIONID=91569ADEF9D501B8071BD59D0DC04E82; Path=/
Location: http://pungjoo.com/servlet/com.pungjoo.blog2005.Action
Content-Type: text/html;charset=EUC-KR
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive

Connection to pungjoo.com closed by foreign host.

위에 Connection to pungjoo.com closed by foreign host. 메시지가 바로 나오는 것이 아니라 5초 후에 나오게 됩니다.
즉 server/client의 구간은 지속됨을 알수 있습니다.

$ telnet pungjoo.com 80
Trying 121.124.124.74...
Connected topungjoo.com.
Escape character is '^]'.
GET / HTTP/1.1
Host: pungjoo.com
Connection: Keep-Alive

HTTP/1.1 302 Moved Temporarily
Date: Tue, 15 Jan 2008 01:36:26 GMT
Set-Cookie: JSESSIONID=2B3EE2FE56868BD9588A7B55C405974B; Path=/
Location: http://pungjoo.com/servlet/com.pungjoo.blog2005.Action
Content-Type: text/html;charset=EUC-KR
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive

GET / HTTP/1.1
Host: pungjoo.com
Connection: Keep-Alive

HTTP/1.1 302 Moved Temporarily
Date: Tue, 15 Jan 2008 01:36:35 GMT
Set-Cookie: JSESSIONID=E4E3D9B9CFE3693DC5AFC3D6ABDE5564; Path=/
Location: http://pungjoo.com/servlet/com.pungjoo.blog2005.Action
Content-Type: text/html;charset=EUC-KR
Content-Length: 0
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive

Connection to pungjoo.com closed by foreign host.


위 예제를 보시면 알겠지만 telnet(연결)은 한번 사용했고 GET method를 2번 날렸습니다. 즉 이렇게 할수 있는 이유는 keep alive 기능때문에 가능한 것 입니다.

참고로 보면 Keep-Alive: timeout=5, max=99 부분에서 max가 감소를 하는 것을 볼수 있는데 이는 최초 연결된 port에 대해서 100회 request를 받겠다는 의미입니다.

HTTP1.0으로 해 보겠습니다. 즉 keep alive 기능이 없음.

$ telnet pungjoo.com 80
Trying 121.124.124.74...
Connected to pungjoo.com.
Escape character is '^]'.
GET / HTTP/1.0
Host: pungjoo.com

HTTP/1.1 302 Moved Temporarily
Date: Tue, 15 Jan 2008 01:33:56 GMT
Set-Cookie: JSESSIONID=B4329BFEDB1363BB90FCFA9568DDBF0B; Path=/
Location: http://pungjoo.com/servlet/com.pungjoo.blog2005.Action
Content-Type: text/html;charset=EUC-KR
Content-Length: 0
Connection: close

Connection to pungjoo.com closed by foreign host.

이번 경우는 response가 날라 오고 바로 'Connection to pungjoo.com closed by foreign host.'로 나와 버립니다. 즉 바로 server/client에서 끊어 버립니다.

@

 

4 Comments
  • 프로필사진 딴따라 2009.10.22 12:23 HTTP/1.1 로 바뀌면서 Keep-Alive는 사뭇 다르게 사용는 것으로 알고 있습니다.
    HTTP/1.0 에서는
    1. Default 가 Close이고
    2. Connection: Keep-Alive 를 사용했을 경우에 Keep-Alive 로 동작하는 반면
    HTTP/1.1 에서는
    1. Default가 Keep-Alive로 동작하고
    2. Connection: Close를 사용했을 때 one time 용으로 동작함

    아닌가요?
  • 프로필사진 딴따라 2009.10.23 14:13 아 오해의 소지가 있었네요.
    1.0 에서 Keep-Alive 가 분명히 존재했고 그 기본 behavior 가 Close라는 말은 아니였습니다. ^^*

    RFC 1945 에서는 "Keep-Alive" 라는 문구 자체가 존재하지 않습니다.
    로이필딩의 추가 노트에서 언급이 되었지요.
    http://www.ics.uci.edu/pub/ietf/http/hypermail/1995q4/0063.html (Roy T. Fielding. Keep-alive notes, Oct 10 1995.)

    때문에 1.0 에서는 양단간에 (Connection 및 Keep-Alive 헤더를 이해하고 그 기능을 제공해야만 비로소 persistent connection 이 이루어진다는 것은 맞는 말씀입니다.)

    HTTP/1.1 (RFC-2616) 에서 다음 부분에 언급되었듯이 1.1 에서는 기본적으로 (별도의 처리 ex) Connection: Close) 을 하지 않는 한 persistent connection이 가능한 것으로 보입니다. (물론 timeout이 되겠지만요)
    --------------------------------------
    8.1.2 Overall Operation
    A significant difference between HTTP/1.1 and earlier versions of HTTP is that persistent connections are the DEFAULT BEHAVIOR of any HTTP connection. That is, unless otherwise indicated, the client SHOULD assume that the server will maintain a persistent connection, even after error responses from the server.

    제 북마크에도 있는 링크지만 언급해 주신 링크(http://www.io.com/~maus/HttpKeepAlive.html) 에 명확한 문구가 있네요.

    HTTP/1.0

    Under HTTP 1.0, there is no official specification for how keepalive operates. It was, in essence, tacked on to an existing protocol. If the browser supports keep-alive, it adds an additional header to the request:

    Connection: Keep-Alive

    Then, when the server receives this request and generates a response, it also adds a header to the response:

    Connection: Keep-Alive

    Following this, the connection is NOT dropped, but is instead kept open. When the client sends another request, it uses the same connection. This will continue until either the client or the server decides that the conversation is over, and one of them drops the connection.

    HTTP/1.1

    Under HTTP 1.1, the official keepalive method is different. All connections are kept alive, unless stated otherwise with the following header:

    Connection: close

    The Connection: Keep-Alive header no longer has any meaning because of this.

    Additionally, an optional Keep-Alive: header is described, but is so underspecified as to be meaningless. Avoid it.



    --------------------------------------------
    1.0 에서는 persistence-connection에 관한 명확한 언급 차제가 없으며 Client/Server 둘다 Conneciton과 Keep-Alive 등의 header 를 해석할 수 있는 기능이 구현되어 있어야 하는 듯 하구요.
    HTTP/1.1 에서는 기본적으로 Persistent-Connection(Keep-Alive) 모드로 동작하는 것으로 알고 있어야 하는 듯 합니다. (Connection: Keep-Alive 헤더는 불필요함)

    같은 말씀에 첨언 쪼끔 한다는 것이 행여 기분을 언짢게 해드린 것은 아닌지 죄송한 마음이 듭니다.
    좋은 blog 감사합니다.
    제 의견이 (아무리 첨언일지언정) 틀릴 수도 있으니 미리 사과드립니다.
  • 프로필사진 굴돌 2011.01.27 14:20 적절한 예로 쉽게 설명해주셔서 고맙습니다. ^^
  • 프로필사진 Favicon of https://xtales.tistory.com Nightly Luna 2015.08.11 09:45 신고 잘 보고 갑니다
댓글쓰기 폼