Как проверить количество открытых файлов процессом и лимиты открытых файлов?
Что проверяют
Знаете ли вы, где в Linux лежат реальные лимиты процесса и почему правка limits.conf часто ничего не меняет. Типичное продолжение: сервис падает с Too many open files, лимит подняли, а ошибка вернулась. Что дальше?
Как отвечать
Разведите три уровня и покажите команды для каждого:
- сколько открыто у процесса:
ls /proc/<PID>/fd | wc -l. Это точное число дескрипторов, включая сокеты и пайпы.lsof -p <PID>удобен, чтобы разобрать, что именно открыто, но строк в нём больше: туда попадают отображённые в память библиотеки,cwdи сам бинарник; - лимит конкретного процесса:
cat /proc/<PID>/limits, строкаMax open files, мягкий и жёсткий.ulimit -nиulimit -Hnпоказывают лимиты вашего шелла, а не сервиса; - лимиты ядра:
fs.file-maxзадаёт потолок на всю систему,/proc/sys/fs/file-nrпоказывает, сколько дескрипторов выделено сейчас,fs.nr_openограничивает, до скольких можно поднять жёсткий лимит одного процесса.
Где менять: /etc/security/limits.conf применяет pam_limits, то есть только к сессиям входа. Сервису под systemd нужен LimitNOFILE= в юните, удобно через systemctl edit, затем daemon-reload и рестарт. В Docker это --ulimit nofile=65535:65535 или ulimits в compose. Работающему процессу лимит меняют без рестарта: prlimit --pid <PID> --nofile=65535:65535.
Ошибки тоже различаются: EMFILE значит упёрлись в лимит процесса, ENFILE в системный. Для мониторинга есть process_open_fds и process_max_fds, их отдают клиентские библиотеки Prometheus, а node_exporter даёт node_filefd_allocated на уровне узла.
Где спотыкаются
Проверяют ulimit -n в своём терминале и делают вывод о сервисе. У процесса, запущенного systemd, лимит свой, и мягкий по умолчанию обычно 1024.
Правят limits.conf для systemd-сервиса и удивляются, что после рестарта ничего не поменялось.
Поднимают лимит до миллиона и считают проблему решённой. Если число дескрипторов растёт со временем без остановки, это утечка: незакрытые файлы или сокеты в CLOSE_WAIT. Лимит только отодвигает падение, смотреть надо через lsof, что копится.