Ответ
Исчерпание лимита файловых дескрипторов (FD) — частая проблема, ведущая к ошибкам типа "Too many open files". Основные причины:
1. Утечки в приложении (наиболее частая): Процесс открывает файлы, сокеты или каналы, но не закрывает их. Это ошибка программирования.
# Утечка: файл не закрывается явно
file = open('data.log', 'r')
content = file.read()
# process(content)
# Забыли file.close()
# Корректный способ (контекстный менеджер автоматически закрывает файл)
with open('data.log', 'r') as file:
content = file.read()
# process(content)
2. Недостаточно высокие системные лимиты:
- Лимит на процесс (
ulimit -n): По умолчанию может быть 1024, чего мало для серверных приложений (например, веб-сервера с множеством одновременных соединений). - Глобальный лимит системы (
fs.file-max): Определяет максимальное число открытых FD во всей системе.
3. Высокая нагрузка: Легитимное использование большого количества дескрипторов, например, база данных, обслуживающая тысячи соединений, или веб-скрапер, открывающий множество сетевых сокетов.
4. Рекурсивное открытие файлов: Ошибка в логике приложения, приводящая к бесконечному циклу открытия файлов (например, в логгере, который пишет логи об ошибках открытия файла).
Диагностика:
# Проверить глобальное использование
cat /proc/sys/fs/file-nr # Показывает: использовано, свободно, максимум
# Найти процесс с наибольшим количеством открытых FD
lsof | awk '{print $2}' | sort | uniq -c | sort -nr | head
# Проверить лимиты для конкретного процесса (PID)
cat /proc/<PID>/limits | grep "open files"
# Посчитать открытые FD для процесса
ls -1 /proc/<PID>/fd/ | wc -l
Решение: Увеличить лимиты (в /etc/security/limits.conf или через systemd), исправить утечки в коде и оптимизировать логику приложения.