Сокет отклоняет соединения: достигнут MaxConnections
В режиме «экземпляр на соединение» systemd ограничивает число одновременных подключений параметром MaxConnections= (по умолчанию 64). Достигнув предела, сокет перестаёт принимать новые соединения, пока не освободятся прежние.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Предел одновременных соединений мал
Значение по умолчанию рассчитано на редкие обращения. Для сколько-нибудь нагруженной службы его мало.
-
Экземпляры не завершаются
Если обработчик зависает, экземпляры копятся и занимают предел. Внешне это выглядит как отказ в обслуживании.
-
Ограничение на источник
Параметр
MaxConnectionsPerSource=ограничивает число соединений с одного адреса. При работе через прокси все соединения приходят с одного адреса и упираются в него.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Предел, текущее число соединений и сколько их было принято всего.
systemctl show myapp.socket -p MaxConnections -p NConnections -p NAcceptedРаботающие экземпляры обработчика.
systemctl list-units "myapp@*" --no-pager | tail -5Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Значение по умолчанию рассчитано на редкие обращения. Для сколько-нибудь нагруженной службы его мало.
- Как проверить
-
Посмотрите предел и число работающих экземпляров.
systemctl show myapp.socket -p MaxConnections -p NConnections systemctl list-units "myapp@*" --no-pager | head
- Как исправить
-
Поднимите предел или откажитесь от режима по соединению: обычной сетевой службе он не подходит.
sudo systemctl edit myapp.socket # [Socket]\nMaxConnections=256
- Почему происходит
- Если обработчик зависает, экземпляры копятся и занимают предел. Внешне это выглядит как отказ в обслуживании.
- Как проверить
-
Посмотрите живущие экземпляры и их время жизни.
systemctl list-units "myapp@*" --no-pager systemctl show myapp@*.service -p ActiveEnterTimestamp 2>/dev/null | head
- Как исправить
-
Добавьте обработчику ограничение времени работы через
RuntimeMaxSec=: зависший экземпляр будет завершён и освободит место.
- Почему происходит
- Параметр
MaxConnectionsPerSource=ограничивает число соединений с одного адреса. При работе через прокси все соединения приходят с одного адреса и упираются в него.
- Как проверить
-
Посмотрите оба предела.
systemctl show myapp.socket -p MaxConnections -p MaxConnectionsPerSource
- Как исправить
- Поднимите предел на источник или уберите его, если перед службой стоит прокси.
Пример вывода
Предел соединений исчерпан. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
systemd[1]: myapp.socket: Too many incoming connections (64), refusing.
systemd[1]: myapp.socket: Refusing connection from <адрес>.
Связанные ошибки
- Служба не получает сокет при сокет-активации Сокет активен, служба запускается, но не находит переданный дескриптор. Разбор: Accept, FileDescriptorName, соответствие имён.
- Too many tasks: упор в предел TasksMax Служба не может создать новый процесс: достигнут предел TasksMax. Где он задан и как поднять правильно.
- Failed with result 'resources' Состояние resources: systemd не смог выделить ресурсы для запуска службы. Чем отличается от кодов 200-й группы и что проверять.
- Сокет с Accept=yes: на каждое соединение свой экземпляр службы Служба порождает десятки экземпляров: при приёме соединений сокетом на каждое создаётся отдельный процесс.
- Сокет с ReusePort: соединения распределяются неравномерно Несколько экземпляров службы на одном порту: как работает ReusePort и почему нагрузка неравномерна.
- Bad file descriptor в журнале службы Ошибка 9 при операции с файлом: дескриптор закрыт или не тот. Разбор для служб и сокет-активации.
- File exists при создании файла или сокета Ошибка 17: объект уже существует. Разбор для сокетов, файлов блокировки и каталогов службы.
- Gunicorn: WORKER TIMEOUT в журнале службы Рабочие процессы Gunicorn убиваются по таймауту: медленные запросы, блокирующие вызовы, неверный тип обработчика.
Источники
-
systemd.socket(5)
MaxConnections=, MaxConnectionsPerSource=, Accept=. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено нагрузкой на сокет с MaxConnections=2.