Miscellaneous

Keepalive란?

강철지그·2017년 12월 5일·조회 9,366

1. 개요

본 문서는 Keepalive에 대한 정리이다. 여기서 말하는 Keepalive는 문맥에 따라 HTTP 연결 재사용을 의미할 수도 있고, TCP 레벨에서 유휴 연결의 생존 여부를 확인하는 기능을 의미할 수도 있다. 두 기능은 목적과 동작 위치가 다르므로 구분해서 이해하는 것이 좋다.


2. Keepalive

2-1. HTTP Keepalive

  • HTTP/1.1부터 기본적으로 지원하는 기능으로, 하나의 TCP 연결을 여러 HTTP 요청에 재사용하는 방식이다. 즉, 매 요청마다 TCP Handshake 과정을 반복하지 않아도 되므로 성능 향상을 기대할 수 있다.
  • 단, 모든 TCP 세션을 무한정 유지할 수는 없으므로 Timeout 및 Max 설정을 통해 관리되어야 한다.
  • keepAliveTimeout: 요청에 대한 응답을 보낸 뒤, 다음 요청을 기다리는 Timeout timer가 동작하기 시작한다.
  • 최근에는 네트워크 환경이 개선되고, 서버 자원을 효율적으로 사용하려는 요구가 커지면서 keepAliveTimeout을 과도하게 길게 두기보다는 비교적 짧게 설정하는 경우가 많다.
  • Event-driven 구조로 non-blocking I/O를 사용하는 Nginx 등은 Keepalive 연결을 유지하더라도 요청 처리 스레드를 계속 점유하지 않기 때문에 동시 처리에 유리하다.

2-2. ThreadPool과 Keepalive

  • 웹 서버만 놓고 볼 때, 웹 서버 역시 ThreadPool을 사용하는 방식으로 설정할 수 있다.
  • Thread-per-connection 또는 Thread-per-request 방식의 서버에서는 동시 접속 수와 ThreadPool 크기가 밀접하게 관련된다. 동시 사용자가 500명이라면 최소한 500개 이상의 ThreadPool이 필요하다고 단순 계산할 수 있지만, 실제로는 요청 처리 시간, Keepalive 유휴 시간, 연결당 요청 수 등을 함께 고려해야 한다.
  • 하나의 웹 페이지 호출 시 사용자는 동시에 여러 Connection을 생성할 수 있다. 만약 특정 웹 페이지 하나를 구성하는 데 많은 자원이 필요하다면 ThreadPool은 그에 비례하여 증가시켜야 한다.
  • 이때 Keepalive까지 적용되어 있다면 실제 요청을 처리 중인 Thread뿐만 아니라, 유휴 상태로 유지되는 연결까지 고려하여 ThreadPool 및 Connection 관련 설정을 해야 한다.
  • 반대로 Event-driven 기반 서버에서는 유휴 Keepalive 연결이 곧바로 동일한 수의 Thread 점유로 이어지지 않을 수 있다. 따라서 사용하는 웹 서버의 동작 모델을 먼저 확인하는 것이 중요하다.

2-3. 동시 사용자 계산과 Keepalive

  • 초당 50TPS 시스템 기준
  • 사용자 요청 간격 10초
  • 동시 사용자는 500명: 50TPS X 10초 = 500명
  • 한 화면당 3개 Connection을 사용하고, Keepalive 시간이 요청 간격과 동일한 10초라면 총 Connection 수는 1,500개로 계산할 수 있다: 50TPS X 10초 X 3개 = 1,500개

위 계산은 단순 산식이므로 실제 운영 환경에서는 브라우저의 동시 연결 정책, 정적 리소스 수, 프록시 또는 로드밸런서의 연결 재사용 방식, 서버의 Timeout 설정에 따라 달라질 수 있다. 따라서 부하 테스트 시에는 TPS뿐만 아니라 활성 Connection 수, 유휴 Connection 수, Thread 사용량, 응답 시간도 함께 확인해야 한다.


3. Keepalive 활용

3-1. 데드 피어 식별

TCP Keepalive는 오랫동안 데이터 송수신이 없는 연결에 대해 상대방이 여전히 살아 있는지 확인하는 데 사용할 수 있다. 예를 들어 클라이언트가 비정상 종료되었거나 중간 네트워크 장비에서 세션이 끊어진 경우, 애플리케이션이 이를 즉시 알지 못할 수 있다. 이때 TCP Keepalive 설정을 통해 데드 피어를 식별하고 불필요한 연결을 정리할 수 있다.

3-2. Disconnection 방지

일부 방화벽, NAT, 로드밸런서는 일정 시간 동안 트래픽이 없는 세션을 정리한다. 장시간 유지되어야 하는 연결이라면 TCP Keepalive 또는 애플리케이션 레벨의 주기적인 ping/pong 메시지를 통해 유휴 세션이 중간 장비에서 끊어지는 것을 줄일 수 있다.

다만 Keepalive 값을 무조건 길게 또는 짧게 설정하는 것이 정답은 아니다. 너무 짧으면 불필요한 패킷과 서버 자원 사용이 늘고, 너무 길면 죽은 연결을 늦게 감지한다. 서비스 특성, 네트워크 장비의 idle timeout, 서버의 Connection/Thread 한계를 함께 고려해 설정해야 한다.

댓글 1

로그인 후 댓글을 남길 수 있습니다.

  • 몽상가몽상가· 2018년 8월 29일
    한 화면 당 3개 Connection 사용하고 keepAlive가 요청 간격과 동일한 10초라면 총 Connection 수는 1,000개 (50TPS X 10초 X 2개) 가 아니라 50TPS X 10초 X 3개이므로 Connection 수는 1,500개여야 하는거 아닌지요??