Наш сервер недавно исчерпал файловые дескрипторы, и в связи с этим у меня есть несколько вопросов. ulimit -n
должен дать мне максимальное количество дескрипторов открытых файлов. Это число 1024. Я проверил количество открытых файловых дескрипторов, запустив его, lsof -u root |wc -l
и получил 2500 fds. Это намного больше, чем 1024, поэтому я догадался, что это будет означать, что число 1024 для каждого процесса, а не для пользователя, как я. Ну, я побежал lsof -p$PidOfGlassfish|wc -l
и получил 1300. Это часть, которую я не понимаю. Если ulimit -n
это не максимальное количество процессов на пользователя или на процесс, то для чего это нужно? Это не относится к пользователю root? И если да, то как я могу получить сообщения об ошибке исчерпания дескриптора файла?
РЕДАКТИРОВАТЬ: Единственный способ, которым я могу разобраться, ulimit -n
- это применить количество открытых файлов (как указано в руководстве по bash), а не количество дескрипторов файлов (разные процессы могут открывать один и тот же файл). Если это так, то просто перечисляя количество открытых файлов (по оглавлению «/», таким образом , исключая файлы , отображенные на память) является не достаточными полномочиями :
lsof -u root |grep /|sort -k9 |wc -l #prints '1738'
Чтобы реально увидеть количество открытых файлов, мне нужно отфильтровать по столбцу имени только печать уникальных записей. Таким образом, следующее, вероятно, более правильно:
lsof -u root |grep /|sort -k9 -u |wc -l #prints '604'
Приведенная выше команда ожидает вывод в следующем формате из lsof:
java 32008 root mem REG 8,2 11942368 72721 /usr/lib64/locale/locale-archive
vmtoolsd 4764 root mem REG 8,2 18624 106432 /usr/lib64/open-vm-tools/plugins/vmsvc/libguestInfo.so
Это, по крайней мере, дает мне число меньше 1024 (число, сообщаемое ulimit -n
), так что это похоже на шаг в правильном направлении. «К сожалению» я не испытываю никаких проблем с исчерпанием файловых дескрипторов, поэтому мне будет трудно это проверить.
источник
Ответы:
Я проверял это в Linux версии 2.6.18-164.el5 - Red Hat 4.1.2-46. Я мог видеть, что ulimit применяется на процесс.
Параметр устанавливается на уровне пользователя, но применяется для каждого процесса.
Например: 1024 был предел. Было запущено несколько процессов, и файлы, открытые каждым из них, были подсчитаны с использованием
Не было ошибок, когда сумма файлов, открытых несколькими процессами, пересекла 1024. Я также проверил уникальное количество файлов, объединяющее результаты для разных процессов и подсчет уникальных файлов. Ошибки начали появляться только тогда, когда счетчик для каждого процесса превысил 1024. (java.net.SocketException: слишком много открытых файлов в журналах процессов)
источник
lsof -p$PidOfGlassfish|wc -l
дал мне 1300? Я предполагаю, что два подхода к подсчету как-то различаются. Если нет, то, возможно, ограничение не распространяется на пользователя root?ls -l
вместоls
? Последний имеет дополнительную строку (напримерtotal 5
), когда есть 5 файлов. В таком случае использованиеls -l
в приведенном выше примере сообщит 6, а не 5. Я используюls /proc/<pid>/fd | wc -l
.ls -l
выдает мне по одной записи на строку, которую я затем перенаправляю во что-то другое. Конечно, это также происходит при нормальном трубопроводеls
(но не иначе).Ulimit для файловых дескрипторов. Это относится к файлам, каталогам, сокетам, каналам epolls, eventfds, timerfds и т. Д. И т. Д.
В любой момент при запуске процессов ограничения могли быть изменены. Посетите
/proc/<pid>/limits
и посмотрите, были ли изменены значения.источник
@oligofren
Я также провел несколько тестов , чтобы определить , как
"ulimits -Sn"
для"open files"
было приведено в исполнение.Как и в случае постера Chosen, упомянутого в ссылке , ulimit для
"open files"
действительно применяется для каждого процесса. Чтобы увидеть текущие ограничения процесса:cat /proc/__process_id__/limits
Чтобы определить, сколько файлов открыт у процесса, вам нужно использовать следующую команду:
lsof -P -M -l -n -d '^cwd,^err,^ltx,^mem,^mmap,^pd,^rtd,^txt' -p __process_id__ -a | awk '{if (NR>1) print}' | wc -l
Объяснение вышеизложенного и мой метод / результаты тестирования
Эти
"-P -M -l -n"
аргументы LSOF просто там , чтобы сделать Lsof работать как можно быстрее. Не стесняйтесь вынимать их.В
"-d '^cwd,^err,^ltx,^mem,^mmap,^pd,^rtd,^txt'"
аргумент инструктируетlsof
исключить дескрипторы файлов типа: УХО / ERR / LTX / MEM / ММАП / PD / ТПС / TXT.Из справочной страницы lsof:
Я счел
"Lnn,jld,m86,tr,v86"
это неприменимым для Linux и поэтому не удосужился добавить их в список исключений. Я не уверен в этом"Mxx"
.Если ваше приложение использует файлы , отображенные на память / устройство , то вы можете удалить
"^mem"
и"^mmap"
из списка исключений.РЕДАКТИРОВАТЬ --- начать отрывать ---
Изменить: я нашел следующую ссылку, которая указывает, что:
Так что, если ваш процесс использует файлы с отображением в памяти, вам нужно отфильтровать * .so файлы.
Кроме того, JVM от Sun будет хранить файлы JAR карты памяти.
Таким образом, такие вещи, как tomcat / glassfish также будут отображать файлы jar с отображенной памятью. Я не проверял, относятся ли они к
"ulimit -Sn"
пределу.РЕДАКТИРОВАТЬ --- конец обрезки ---
Опытным путем я обнаружил, что
"cwd,rtd,txt"
они не учитываются в отношении лимита на файл процесса (ulimit -Sn).Я не уверен,
"err,ltx,pd"
учитывается ли ограничение на количество файлов, поскольку я не знаю, как создавать файловые дескрипторы этих типов дескрипторов.В
"-p __process_id__"
аргументе ограничиваетlsof
только возвращать информацию для__process_id__
указания. Удалите это, если вы хотите получить счет для всех процессов."-a"
Аргумент используется для И на выбор (то есть «-p» и «-d» аргументы).Оператор
"awk '{if (NR>1) print}'"
используется для пропуска заголовка, которыйlsof
печатается в его выводе.Я тестировал, используя следующий Perl-скрипт:
Мне пришлось выполнить скрипт в отладчике perl, чтобы скрипт не завершился и не освободил файловые дескрипторы.
Выполнить:
perl -d test.pl
В отладчике perl вы можете запустить программу, введя
c
и нажав Enter, и если у васulimit -Sn
было значение 1024 , вы обнаружите, что программа останавливается после созданияTest1017.log
файла в/tmp
.Если вы теперь идентифицируете pid процесса perl и используете указанную выше
lsof
команду, вы увидите, что она также выдает 1024 .Удалите
"wc -l"
и замените на,"less"
чтобы увидеть список файлов, которые учитываются в пределе 1024 . Удалите"-d ^....."
аргумент, а видеть , чтоcwd,txt
иrtd
дескрипторы не засчитываются предел.Если вы сейчас запустите
"ls -l /proc/__process_id__/fd/ | wc -l"
, вы увидите возвращенное значение 1025 . Это связано с тем,ls
что"total 0"
в вывод добавлен заголовок, который был подсчитан.Замечания:
Чтобы проверить, заканчивается ли в ОС дескрипторы файлов, лучше сравнить значение:
cat /proc/sys/fs/file-nr | awk '{print $1}'
с
cat /proc/sys/fs/file-max
https://www.kernel.org/doc/Documentation/sysctl/fs.txt описывает, что
file-nr
и чтоfile-max
означает.источник
Похоже, ваши рассуждения звучат примерно так: «Мне нужно снизить этот предел, чтобы у меня не заканчивались драгоценные дескрипторы». На самом деле все наоборот: если на вашем сервере заканчиваются файловые дескрипторы, вам нужно поднять этот предел с 1024 до чего-то большего. Для реалистичной
glassfish
реализации 32 768 разумно.Лично я всегда поднимаю лимит примерно до 8 192 по всей системе - 1024 просто смешно. Но вы хотите поднять
glassfish
выше. Проверьте/etc/security/limits.conf
. Вы можете добавить специальную запись для пользователя, которыйglassfish
запускается как.источник
Вы хотите взглянуть на общесистемные ограничения, установленные в / proc / sys / fs / file-max, и отрегулировать их там (до следующей перезагрузки) или установить fs.file-max в sysctl.conf, чтобы сделать его постоянным. Это может быть полезно - http://www.randombugs.com/linux/tuning-file-descriptors-limits-on-linux.html
источник
Распространенная ошибка - сравнивать результат необработанного вызова lsof с предполагаемым пределом.
Для глобального ограничения (/ proc / sys / fs / file-max) вы должны взглянуть на / proc / sys / fs / file-nr -> значение fist указывает, что используется, а последнее значение - ограничение
Ограничение OpenFile для каждого процесса, но может быть определено для пользователя, см. Команду "ulimit -Hn" для ограничений пользователя и см. /Etc/security/limits.conf для определений. Обычно применяется с «пользователем приложения», например: «tomcat»: установите ограничение в 65000 для пользователя tomcat, который будет применяться к процессу Java, который он запускает.
Если вы хотите проверить лимит, примененный к процессу, получите его PID, а затем: cat / proc / $ {PID} / limit. Если вы хотите проверить, сколько файлов открывается процессом, получите его PID, а затем: ls -1 / proc / {PID} / fd | wc -l (обратите внимание, для ls это «минус один», не путать с «минус эль»)
Если вы хотите узнать подробности с помощью lsof, но только для тех обработчиков файлов, которые учитывают лимит, попробуйте выполнить следующее: lsof -p $ {PID} | grep -P "^ (\ w + \ s +) {3} \ d + \ D +" lsof -p $ {PID} -d '^ cwd, ^ err, ^ ltx, ^ mem, ^ mmap, ^ pd, ^ rtd, ^ txt '-a
Замечание: «файлы» - это файлы / pipe / TCP-соединения / и т. Д.
Обратите внимание, что иногда вам, вероятно, понадобится быть пользователем root или использовать sudo для получения правильного результата для команд, без привилегий иногда у вас нет ошибок, просто меньше результатов.
и, наконец, если вы хотите знать, к каким «файлам» в вашей файловой системе обращается процесс, взгляните на: lsof -p {PID} | grep / | awk '{print $ 9}' | сортировать | уник
веселиться !
источник