Служба не создаёт потоки: упор в предел
Сообщения вроде «can not create thread» и «Resource temporarily unavailable» при создании потока означают упор в предел задач. Потоки считаются наравне с процессами, поэтому многопоточная служба расходует предел быстрее, чем кажется.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Исчерпан предел задач службы
Каждый поток — задача в контрольной группе. Приложение с пулом потоков на каждое соединение упирается в предел под нагрузкой.
-
Исчерпан системный предел процессов
Общий предел ядра ограничивает суммарное число задач на машине. При его исчерпании отказывают все службы.
-
Утечка потоков в приложении
Потоки создаются и не завершаются. Число растёт монотонно, и любой предел рано или поздно исчерпается.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Текущее число задач и предел рядом.
systemctl status myapp.service --no-pager | grep -i tasksТочное число потоков главного процесса.
PID=$(systemctl show -p MainPID --value myapp.service); ls /proc/$PID/task | wc -lКто на машине создал больше всего задач.
systemd-cgtop -1 --order=tasks | head -10Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Каждый поток — задача в контрольной группе. Приложение с пулом потоков на каждое соединение упирается в предел под нагрузкой.
- Как проверить
-
Посмотрите предел и текущее число задач.
systemctl show myapp.service -p TasksMax -p TasksCurrent systemctl status myapp.service --no-pager | grep -i tasks
- Как исправить
-
Поднимите
TasksMax=с запасом относительно пикового числа потоков или ограничьте размер пула в самом приложении.
- Почему происходит
- Общий предел ядра ограничивает суммарное число задач на машине. При его исчерпании отказывают все службы.
- Как проверить
-
Посмотрите предел и текущее число.
cat /proc/sys/kernel/pid_max ps -eLf | wc -l
- Как исправить
-
Поднимите
kernel.pid_maxи найдите службу, создающую основную массу задач.
- Почему происходит
- Потоки создаются и не завершаются. Число растёт монотонно, и любой предел рано или поздно исчерпается.
- Как проверить
-
Посмотрите число потоков в динамике.
PID=$(systemctl show -p MainPID --value myapp.service); ls /proc/$PID/task | wc -l; sleep 30; ls /proc/$PID/task | wc -l
- Как исправить
- Разбирайтесь с приложением: рост числа потоков при неизменной нагрузке — это дефект, а не вопрос настройки.
Пример вывода
Служба упёрлась в предел задач. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
myapp[1200]: fatal: can not create thread: Resource temporarily unavailable
$ systemctl status myapp.service | grep Tasks
Tasks: 512 (limit: 512)
Связанные ошибки
- Too many tasks: упор в предел TasksMax Служба не может создать новый процесс: достигнут предел TasksMax. Где он задан и как поднять правильно.
- Failed with result 'resources' Состояние resources: systemd не смог выделить ресурсы для запуска службы. Чем отличается от кодов 200-й группы и что проверять.
- Too many open files в журнале службы Служба исчерпала лимит файловых дескрипторов. Как правильно поднять LimitNOFILE и когда дело в утечке.
- Cannot allocate memory в журнале службы Не удалось выделить память: предел службы, память машины, настройка overcommit, исчерпанные области отображения.
- Disk quota exceeded для службы Место на разделе есть, а запись отклоняется: исчерпана дисковая квота пользователя или группы.
- Elasticsearch: max virtual memory areas vm.max_map_count is too low Elasticsearch отказывается стартовать из-за заниженного vm.max_map_count. Как поднять значение и закрепить его.
- No buffer space available в журнале службы Ошибка 105: нет места в буферах ядра. Разбор для сети и таблиц соседей.
- No space left on device в журнале службы Нет места на устройстве: разбор по свободным блокам, по inode, по журналу systemd и по удалённым, но открытым файлам.
Где встречается чаще всего
Источники
-
systemd.resource-control(5)
TasksMax= и учёт потоков. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено многопоточным приложением при TasksMax=64.