Ответ
Сначала я подтверждаю причину падения, проверив логи приложения и системный журнал (journalctl -xe) на наличие ошибок EMFILE (Too many open files).
Затем анализирую текущее состояние:
# Проверяю лимит для текущей оболочки и для PID упавшего процесса
ulimit -n
cat /proc/<PID>/limits | grep 'Max open files'
# Смотрю общее использование файловых дескрипторов в системе
cat /proc/sys/fs/file-nr
# Вывод: 1024 0 9223372036854775807
# | | |
# | | максимальный лимит системы
# | свободные FD
# выделенные FD
# Определяю, какие процессы держат много дескрипторов
lsof | awk '{print $2}' | sort | uniq -c | sort -nr | head
Временное решение для восстановления работы: увеличиваю лимит для сессии и перезапускаю сервис.
ulimit -n 65536
systemctl restart application.service
Постоянное решение:
- Для всех пользователей/процессов: редактирую
/etc/security/limits.conf.* soft nofile 65536 * hard nofile 65536После правки требуется перелогин.
- Для systemd-сервисов (наиболее надежный метод в современных дистрибутивах) правлю юнит-файл или создаю дроп-ин:
# /etc/systemd/system/application.service.d/limits.conf [Service] LimitNOFILE=65536Применяю:
systemctl daemon-reload && systemctl restart application. - Увеличиваю системный лимит, если нужно:
echo 'fs.file-max = 2097152' >> /etc/sysctl.conf sysctl -p
Расследование утечки:
# Мониторю рост открытых файлов у конкретного процесса
watch -n 1 'ls -1 /proc/<PID>/fd | wc -l'
# Ищу удаленные, но все еще открытые файлы (частая проблема с логами)
lsof -p <PID> | grep deleted
В приложении ищу места, где не закрываются файлы, сокеты или соединения с БД, особенно в циклах или при ошибках.