← 아티클 목록

TCP keepalive 설정과 timeout 튜닝 실전 가이드

2027-07-26#networking#tcp#timeout

서버 로그에 멀쩡한데 클라이언트는 "응답이 없다"고 합니다. 흔한 원인은 죽은 연결을 양쪽이 모르고 붙들고 있는 상황입니다. TCP는 데이터를 주고받지 않는 동안에는 상대가 살아있는지 확인하지 않기 때문입니다. keepalive와 timeout은 이 좀비 커넥션을 정리하는 두 축입니다.

keepalive — 죽은 연결을 감지한다

TCP keepalive는 유휴 연결에 주기적으로 작은 탐침을 보내 상대가 살아있는지 확인합니다. 리눅스의 커널 파라미터는 셋입니다.

로컬 터미널
sysctl net.ipv4.tcp_keepalive_time     # 유휴 후 첫 탐침까지(기본 7200초)
sysctl net.ipv4.tcp_keepalive_intvl    # 탐침 재전송 간격(기본 75초)
sysctl net.ipv4.tcp_keepalive_probes   # 실패 허용 횟수(기본 9회)

기본값 7200초는 2시간입니다. 끊긴 연결을 2시간이나 붙들고 있는 셈이라, 운영 환경에서는 보통 줄입니다.

로컬 터미널
# 임시 적용
sysctl -w net.ipv4.tcp_keepalive_time=300
sysctl -w net.ipv4.tcp_keepalive_intvl=30
sysctl -w net.ipv4.tcp_keepalive_probes=3

이 설정이면 유휴 300초 뒤 30초 간격으로 3번 탐침을 보내고, 모두 실패하면 연결을 끊습니다. 즉 약 300 + 30*3 = 390초 안에 죽은 연결을 감지합니다.

timeout — 여러 종류를 구분하라

timeout은 한 종류가 아닙니다. 어느 단계에서 기다리다 포기하느냐에 따라 다릅니다.

timeout 종류의미너무 길면너무 짧으면
connect timeout연결 수립까지 대기장애 감지 지연느린 망에서 실패
read timeout응답 데이터 대기느린 백엔드에 매달림정상 요청도 끊김
idle timeout유휴 연결 유지 시간커넥션 누수재연결 비용 증가

connect는 짧게(수 초), read는 백엔드 처리 시간보다 약간 길게 잡는 것이 출발점입니다.

둘을 함께 맞춰야 하는 이유

흔한 함정은 계층 간 timeout이 어긋나는 것입니다. 예를 들어 리버스 프록시의 idle timeout이 60초인데 백엔드의 keepalive idle은 120초라면, 프록시가 먼저 끊은 연결을 백엔드가 살아있다고 믿고 재사용하다 connection reset을 만납니다.

규칙은 단순합니다. 앞단(프록시·LB)의 idle timeout을 뒷단보다 짧게 두어, 끊는 쪽을 한쪽으로 정합니다.

로컬 터미널
# 현재 연결 상태와 타이머 관찰
ss -tan state established        # 맺어진 연결 목록
ss -tani                         # keepalive 타이머 등 상세

체크리스트

로컬 터미널
sysctl net.ipv4.tcp_keepalive_time    # 현재 keepalive 유휴값 확인
sysctl -w net.ipv4.tcp_keepalive_time=300   # 운영용으로 단축
ss -tan state established              # 좀비 커넥션 누적 확인
# 앞단 idle timeout < 뒷단 idle timeout 으로 정렬

TCP 연결 상태와 timeout을 직접 관찰하고 튜닝하는 실습은 네트워크 트랙에서 회원가입 없이 무료로 해볼 수 있습니다.