Иногда TCP-соединение выглядит живым, хотя в реальности удаленная сторона уже давно недоступна. Например:
- клиент выключился;
- оборвался VPN;
- пропал маршрут;
- firewall удалил state;
- NAT-сессия протухла;
- сервер завис без корректного закрытия соединения.
Если по соединению нет трафика, приложение может еще долго считать его активным.
Для таких случаев в TCP есть механизм keepalive.
▪️ Проверить текущие настройки linux:
sysctl net.ipv4.tcp_keepalive_time sysctl net.ipv4.tcp_keepalive_intvl sysctl net.ipv4.tcp_keepalive_probes Типичная логика такая:tcp_keepalive_time- сколько ждать простоя до первой проверкиtcp_keepalive_intvl- интервал между проверкамиtcp_keepalive_probes- сколько неудачных попыток сделать Например:
sysctl -w net.ipv4.tcp_keepalive_time=300 sysctl -w net.ipv4.tcp_keepalive_intvl=30 sysctl -w net.ipv4.tcp_keepalive_probes=5 В этом случае после 5 минут простоя ядро начнет проверять соединение, а при отсутствии ответа будет делать повторные попытки. ▪️ Для постоянной настройки:
cat > /etc/sysctl.d/99-tcp-keepalive.conf <<'EOF' net.ipv4.tcp_keepalive_time=300 net.ipv4.tcp_keepalive_intvl=30 net.ipv4.tcp_keepalive_probes=5 EOF sysctl --system ▪️ Посмотреть активные TCP-соединения:
ss -nto ▪️ Подробнее по конкретному соединению:
ss -ti
Но есть важный нюанс: системные значения работают только для сокетов, где приложение вообще включило SO_KEEPALIVE. То есть одной настройки sysctl иногда недостаточно. Например, nginx, PostgreSQL, HAProxy, SSH и различные runtime могут иметь собственные keepalive-параметры.
▪️ У SSH есть похожий механизм на уровне приложения:
ServerAliveInterval 30 ServerAliveCountMax 3
Это уже не TCP keepalive, но задача похожая — быстрее понять, что удаленная сторона больше не отвечает.
