Проверьте открытый предел FD для данного процесса в Linux
недавно у меня был процесс Linux, который "слил" файловые дескрипторы: он открыл их и не закрыл должным образом некоторые из них.
если бы я контролировал это, я мог бы сказать-заранее-что процесс достиг своего предела.
есть ли хороший, BashPython способ проверить коэффициент использования FD для данного процесса в системе Ubuntu Linux?
EDIT:
теперь я знаю, как проверить, сколько открытых файловых дескрипторов есть; я только нужно знать сколько дескрипторов файлов разрешено для процесса. Некоторые системы (например, Amazon EC2) не имеют .
спасибо,
Udi
7 ответов:
подсчитайте записи в
/proc/<pid>/fd/
. Жесткие и мягкие ограничения, применяемые к процессу, можно найти в/proc/<pid>/limits
.
единственными интерфейсами, предоставляемыми ядром Linux для получения ограничений ресурсов, являются
getrlimit()
и/proc/
pid/limits
.getrlimit()
можно получить только ограничения ресурсов вызывающего процесса./proc/
pid/limits
позволяет получить ограничения ресурсов любого процесса с тем же идентификатором пользователя и доступен на RHEL 5.2, RHEL 4.7, Ubuntu 9.04 и любом дистрибутиве с ядром 2.6.24 или более поздней версии.Если вам нужно поддержать старые системы Linux, то вам придется получить сам процесс, чтобы вызвать
getrlimit()
. Конечно, самый простой способ сделать это-изменить программу или библиотеку, которую она использует. Если вы используете программу, то вы можете использоватьLD_PRELOAD
загрузить свой код в программу. Если ни один из них не возможен, вы можете подключиться к процессу с помощью gdb и заставить его выполнить вызов в процессе. Вы также можете сделать то же самое с помощьюptrace()
чтобы подключиться к процессу, вставьте вызовите в своей памяти, и т. д., однако это очень сложно получить право и не рекомендуется.с соответствующими привилегиями другие способы сделать это будут включать просмотр памяти ядра, загрузку модуля ядра или иное изменение ядра, но я предполагаю, что об этом не может быть и речи.
вы просили методы bash / python. ulimit был бы лучшим подходом к bash (за исключением munging through
/proc/$pid/fd
и тому подобное вручную). Для python можно использовать модуль ресурсов.import resource print(resource.getrlimit(resource.RLIMIT_NOFILE))
$ python test.py (1024, 65536)
resource.getrlimit
соответствуетgetrlimit
вызовите программу на языке C. Результаты представляют текущие и максимальные значения для запрошенного ресурса. В приведенном выше примере текущий (мягкий) предел составляет 1024. Значения являются типичными значениями по умолчанию Системы Linux в наши дни.
чтобы увидеть верхний 20 дескриптор файла с помощью процессов:
for x in `ps -eF| awk '{ print }'`;do echo `ls /proc/$x/fd 2> /dev/null | wc -l` $x `cat /proc/$x/cmdline 2> /dev/null`;done | sort -n -r | head -n 20
вывод находится в формате file handle count, pid, cmndline для process
пример вывода
701 1216 /sbin/rsyslogd-n-c5 169 11835 postgres: spaceuser spaceschema [local] idle 164 13621 postgres: spaceuser spaceschema [local] idle 161 13622 postgres: spaceuser spaceschema [local] idle 161 13618 postgres: spaceuser spaceschema [local] idle
в CentOS 6 и ниже (все, что использует GCC 3), Вы можете обнаружить, что настройка ограничений ядра не решает проблему. Это потому, что есть FD_SETSIZE значение, которое устанавливается во время компиляции в использовании GCC. Для этого вам нужно будет увеличить значение, а затем повторно скомпилировать процесс.
кроме того, вы можете обнаружить, что вы утечка дескрипторов файлов из-за известные проблемы в libpthread Если вы используете эту библиотеку. Этот призыв был интегрирован в GCC в GCC 4 / CentOS7/RHEL 7, и это, похоже, исправило проблемы с потоками.
Python wrapper с использованием превосходного пакета psutil:
import psutil for p in psutil.process_iter(attrs=['pid', 'name', 'username', 'num_fds']): try: soft, hard = p.rlimit(psutil.RLIMIT_NOFILE) cur = p.info['num_fds'] usage = int(cur / soft * 100) print('{:>2d}% {}/{}/{}'.format( usage, p.info['pid'], p.info['username'], p.info['name'], )) except psutil.NoSuchProcess: pass