SystemdDoctor
мешает работе сокеты сеть ресурсы

Соединения через сокет-активацию висят и не закрываются

Соединение, оборванное без закрытия, остаётся в таблице ядра часами. Для служб с сокет-активацией это означает исчерпание пределов соединений при отсутствии клиентов. Проверка живости включается в описании сокета и решает задачу без правок в самой службе.

Вероятные причины

По порядку: сверху то, что встречается чаще.

  1. Проверка живости соединений не включена

    Без неё оборванное соединение остаётся открытым до истечения длинных сроков ядра.

  2. Соединения копятся в состоянии ожидания закрытия

    Другая сторона закрыла соединение, а служба не читает до конца. Записи держатся до истечения срока.

  3. Предел соединений исчерпан висящими записями

    Предел считает все соединения, включая мёртвые. Новые клиенты получают отказ при отсутствии живой нагрузки.

Диагностика

Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.

Соединения на порту службы и их состояния.

ss -tanp | grep :8080 | head -20

Проверка живости и пределы соединений.

systemctl show myapp.socket -p KeepAlive -p MaxConnections -p NConnections

Распределение состояний соединений по машине.

ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn | head

Решение

Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.

1. Проверка живости соединений не включена
Почему происходит
Без неё оборванное соединение остаётся открытым до истечения длинных сроков ядра.
Как проверить
Посмотрите параметры сокета и число соединений.
systemctl show myapp.socket -p KeepAlive -p KeepAliveTimeSec
ss -tan state established | wc -l
Как исправить
Включите проверку живости и задайте разумные сроки. Это правильнее, чем менять общие настройки ядра для всей машины.
[Socket]
ListenStream=8080
KeepAlive=true
KeepAliveTimeSec=120
2. Соединения копятся в состоянии ожидания закрытия
Почему происходит
Другая сторона закрыла соединение, а служба не читает до конца. Записи держатся до истечения срока.
Как проверить
Посмотрите распределение состояний соединений.
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn | head
Как исправить
Исправьте закрытие соединений в самой службе. Проверка живости помогает при обрывах, но не заменяет корректного закрытия.
3. Предел соединений исчерпан висящими записями
Почему происходит
Предел считает все соединения, включая мёртвые. Новые клиенты получают отказ при отсутствии живой нагрузки.
Как проверить
Посмотрите предел и число соединений.
systemctl show myapp.socket -p MaxConnections -p NConnections
Как исправить
Поднимите предел и включите проверку живости. Одно без другого лишь отодвигает проблему.

Пример вывода

Предел исчерпан висящими соединениями. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.

systemd[1]: myapp.socket: Too many incoming connections (64), dropping connection.

$ ss -tanp | grep -c ":8080.*ESTAB"
64
$ ss -tanp | grep ":8080" | head -2
ESTAB 0 0 192.0.2.10:8080 192.0.2.55:52310
ESTAB 0 0 192.0.2.10:8080 192.0.2.55:52311

Связанные ошибки

Источники

  • systemd.socket(5)
    KeepAlive=, KeepAliveTimeSec= и пределы соединений.
    официальная документация, systemd 255
    сверено 15 сентября 2026
  • Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
    Проверено на systemd 255: без проверки живости оборванные соединения держат предел.
    собственная проверка, systemd 255
    сверено 15 сентября 2026