Из-за чего в Linux могут закончиться файловые дескрипторы?

«Из-за чего в Linux могут закончиться файловые дескрипторы?» — вопрос из категории Linux, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Исчерпание лимита файловых дескрипторов (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), исправить утечки в коде и оптимизировать логику приложения.