ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [스크랩] Graceful Shutdown에 관하여
    프로그래밍/기록, 개념, 용어 2015. 7. 11. 01:35
    반응형
    3. Graceful Shutdown에 관하여
      위에서 검토한 바와 같이 Buffer에 데이터가 남아있는 상태에서 연결을 강제로 종료할 경우 SendBuffer에 있는 데이터가 유실될 수도 있는데, 이러한 종료방식을 "Abortive Shutdown"이라고 합니다. 반대로 TCP 프로토콜의 4-way Handshake에 따라 데이터 유실 없이 종료하는 것을 "Graceful Shutdown"이라고 합니다.

      인터넷의 TIME_WAIT 관련된 글 중 일부는 Linger 옵션을 사용하여 TIME_WAIT를 남기지 않고 세션을 종료하는 것을 "Graceful Shutdown"이라고 표현한 글이 있는데, 이것은 잘못된 표현입니다. 오히려 TIME_WAIT는 Graceful Shutdown이 이루어지는 과정에서 자연스럽게 발생하는 과정입니다. 억지로 TIME_WAIT를 남기지 않기 위해 Linger 옵션을 사용하는 것은 데이터 유실을 초래할 수도 있으므로 조심해야 합니다. (비록 저도 실제로 이런 경우를 보지는 못했지만... 이론적으로는 그렇다고 합니다. ^^)
      또한 TIME_WAIT가 FIN 신호를 제대로 교환하지 못했기 때문에 발생한다는 의견도 잘못된 것입니다. 위에서 살펴보았듯이 TIME_WAIT는 Graceful Shutdown 과정에서 필수적으로 거쳐가야 할 과정입니다. (실제로 테스트를 해 본 결과, Linger옵션을 조작하는 경우를 제외하면, 어떠한 방식으로 세션을 종료하더라도 서버 혹은 클라이언트 양쪽에 모두 TIME_WAIT가 생기지 않도록 종료하는 방법을 찾지 못했습니다.)

      우리가 지향해야 할 세션 종료는 무조건 TIME_WAIT를 남기지 않는 것이 아니라, TIME_WAIT가 서버 측이 아닌 클라이언트 측에 생기도록 하는 Graceful Shutdown입니다. 이렇게 되기 위해서는 위에서 살펴본 바와 같이 "Client가 먼저 closesocket()을 호출하도록 하는 것"이 가장 중요합니다. 이것을 보장하기 위해서는 Client와 Server 간에 종료 프로토콜을 설계할 때 Client가 먼저 closesocket()을 먼저 호출하도록 반영되어야 합니다. 이것만 확실히 지켜진다면 서버에는 TIME_WAIT가 남지 않습니다.

      다음은 종료 프로토콜의 예입니다. 

    1) 서버에서 클라이언트에 "너 종료해라"는 커맨드를 전송합니다.
    2) "너 종료해라"를 수신한 클라이언트는 서버에 "알았다 종료하겠다"를 전송한 후 즉시 closesocket()를 전송합니다. ( 마지막 통신이 클라이언트 -> 서버 방향으로 일어난다는 것이 중요합니다.)
    3) "알았다 종료하겠다"를 수신한 서버는 해당 소켓에 대해 closesocket()을 호출합니다. 이때 안전장치로 Linger 옵션을 주어 Abortive Shutdown을 시키는 것이 좋습니다. 어차피 서버에서 클라이언트로는 더이상 보낼(유실될) 데이터가 없다는 것이 확인되었고, 간혹 Client 중에 프로토콜을 따르지 않고 종료하는 녀석들이 있기 때문입니다.
    ※ IOCP 를 사용한 서버에서는 주기적으로 마지막 통신한 TimeStamp를 체크하여 Idle Session에 대해 Gabage Collection(?)을 수행해주어야 합니다. 이러한 경우에는 서버측에서 먼저 closesocket()을 호출할 수 밖에 없기 때문에, TIME_WAIT를 남기지 않기 위해 반드시 Linger 옵션으로 Abortive Shutdown을 시켜주어야 합니다.

    클라이언트 측서버 측
    (1) 호출 종료 세션의 끝을 위해 (들, SD_SEND)를 그 클라이언트가 보내 더 이상 데이터가 없습니다.
    (2) FD_CLOSE 진행중인 모든 데이터가 수신 된 것을 정상 종료를 나타내는 수신합니다.
    (3) 나머지 응답 데이터를 전송합니다.
    (로컬 타이밍 의미 만은) FD_READ와 통화 가져 RECV 서버에서 전송 된 응답 데이터를 얻을 수 있습니다.(4) 호출 종료 서버가 보내 더 이상 데이터가없는 표시하기 위해 (들, SD_SEND을).
    (5) FD_CLOSE 표시를 수신합니다.(로컬 타이밍의 중요성은 전용) 호출 closesocket 함수를 .
    (6) 호출 closesocket 함수를 .

     


    http://kuaaan.tistory.com/118

    https://msdn.microsoft.com/en-us/library/ms738547(VS.85).aspx

    반응형
Designed by Tistory.