Ulimit предназначен для дескрипторов файлов. Это применимо к файлам, каталогам, сокетам, epolls каналов, eventfds, timerfds и т. Д.
В любой момент во время запуска процесса ограничения могли быть изменены.
Посетите / proc /
и посмотрите, не были ли изменены значения.
Похоже, вы рассуждали примерно так: «Я должен снизить этот предел, чтобы у меня не закончились драгоценные дескрипторы». На самом деле все обстоит с точностью до наоборот - если на вашем сервере закончились файловые дескрипторы, вам нужно поднять этот предел с 1024 до большего. Для реалистичной реализации Glassfish
разумно 32 768.
Лично я всегда увеличиваю лимит до 8 192 для всей системы - 1024 просто смешно. Но вы захотите поднять стеклянную рыбу
выше. Проверьте /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
Я тестировал это в Linux версии 2.6.18-164.el5 - Red Hat 4.1.2-46. Я видел, что ulimit применяется к процессу.
Параметр устанавливается на уровне пользователя, но применяется для каждого процесса.
Например: 1024 было пределом. Было запущено несколько процессов, и количество файлов, открытых каждым из них, было подсчитано с использованием
ls -l /proc/--$pid--/fd/ | wc -l
. Когда сумма файлов, открытых несколькими процессами, превышала 1024, ошибок не было. Я также проверил количество уникальных файлов, объединив результаты для разных процессов и подсчитав количество уникальных файлов. Ошибки начали появляться только тогда, когда счетчик для каждого процесса перевалил за 1024. (java.net.SocketException: слишком много открытых файлов в журналах процессов)
@oligofren
Я также провел некоторое тестирование, чтобы определить, как "ulimits -Sn"
для "открытых файлов"
применялось. 12165] Как и плакат Chosen , упомянутый в ссылке , ulimit для «открытых файлов»
действительно применяется к каждому процессу. Чтобы узнать, каковы текущие ограничения процесса:
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 работают максимально быстро. Не стесняйтесь снимать их.
-P - inhibits the conversion of port numbers to port names for network files
-M - disable reporting of portmapper registrations for local TCP, UDP and UDPLITE ports
-l - inhibits the conversion of user ID numbers to login names
-n - inhibits the conversion of network numbers to host names for network files
Аргумент "- d '^ cwd, ^ err, ^ ltx, ^ mem, ^ mmap, ^ pd, ^ rtd, ^ txt'"
указывает ] lsof
для исключения файловых дескрипторов типа: cwd / err / ltx / mem / mmap / pd / rtd / txt.
Из справочной страницы lsof:
FD is the File Descriptor number of the file or:
cwd current working directory;
Lnn library references (AIX);
err FD information error (see NAME column);
jld jail directory (FreeBSD);
ltx shared library text (code and data);
Mxx hex memory-mapped type number xx.
m86 DOS Merge mapped file;
mem memory-mapped file;
mmap memory-mapped device;
pd parent directory;
rtd root directory;
tr kernel trace file (OpenBSD);
txt program text (code and data);
v86 VP/ix mapped file;
Я полагал "Lnn, jld, m86 , tr, v86 "
как неприменимые к Linux и поэтому не удосужились добавить их в список исключений. Я не уверен насчет "Mxx"
.
Если ваше приложение использует файлы / устройства с отображением памяти, вы можете удалить «^ mem»
и «^ mmap»
из списка исключений.
РЕДАКТИРОВАТЬ ---begin snip ---
Edit: я нашел следующую ссылку , которая указывает, что:
.so-файлы с отображением памяти технически не то же самое, что и файл, обрабатывающий приложение имеет контроль над. / proc // fd - это точка измерения дескрипторов открытых файлов
Поэтому, если ваш процесс действительно использует файлы с отображением памяти, вам необходимо отфильтровать файлы * .so.
Кроме того, JVM Sun будет отображать карту памяти. jar files
Файл JAR с отображением в память, в данном случае файл, содержащий «классы JDK». Когда вы отображаете JAR-файл в памяти, вы можете очень эффективно получить доступ к файлам в нем (вместо того, чтобы каждый раз читать его с самого начала). Sun JVM будет отображать память для всех JAR в пути к классам; если вашему коду приложения требуется доступ к JAR, вы также можете отобразить его в памяти.
Таким образом, такие вещи, как tomcat / glassfish, также будут отображать файлы jar с отображением памяти. Я не проверял , учитываются ли они в соответствии с пределом "ulimit -Sn"
.
EDIT --- end snip ---
Опытным путем я обнаружил что «cwd, rtd, txt»
не учитываются в отношении ограничения на файл процесса (ulimit -Sn).
Я не уверен, что » err, ltx, pd "
засчитываются в счет ограничения файла, так как я не знаю, как создавать дескрипторы файлов этих типов дескрипторов.
Аргумент " - p __process_id __ "
ограничивает ] lsof
, чтобы возвращать информацию только для указанного __ process_id __
. Удалите это, если вы хотите получить счетчик для всех процессов.
Аргумент «- a»
используется для И выборок (то есть «-p» и «-» d "arguments).
Оператор " awk '{if (NR> 1) print}' "
используется для пропуска заголовка, который lsof
выводит в свой вывод.
Я тестировал, используя следующий сценарий perl:
File: test.pl
---snip---
#!/usr/bin/perl -w
foreach $i (1..1100) {
$FH="FH${i}";
open ($FH,'>',"/tmp/Test${i}.log") || die "$!";
print $FH "$i\n";
}
---snip---
Мне пришлось выполнить сценарий в отладчике perl, чтобы убедиться, что сценарий не завершается и не освобождает дескрипторы файлов.
Для выполнения: perl -d test .pl
В отладчике perl вы можете запустить программу, введя c
и нажав Enter, и если ваш ulimit -Sn
имел значение 1024 , вы обнаружите, что программа останавливается после создания файла Test1017.log
в / tmp
.
Если вы теперь определите pid процесса perl и воспользуетесь указанным выше lsof
вы увидите, что она также выводит 1024 . [1219 6] Удалите «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[12203 providedhttps://www.kernel.org/doc/Documentation/sysctl/fs.txt Документирует, что означают
file-nr
и file-max
.
Распространенная ошибка при сравнении результата необработанного вызова lsof с предполагаемым пределом.
Для глобального ограничения (/ proc / sys / fs / file-max) вам следует посмотреть / proc / sys / fs / file-nr -> первое значение указывает, что используется, а последнее значение является пределом
Ограничение OpenFile есть для каждого процесса, но его можно определить для пользователя, см. команду "ulimit -Hn" ограничения для пользователей и определения в /etc/security/limits.conf. Обычно применяется с «пользователем приложения», например: «tomcat»: установите ограничение на 65000 для пользователя tomcat, которое будет применяться к запускаемому им java-процессу.
Если вы хотите проверить ограничение, примененное к процессу, получите его PID, а затем: cat / proc / $ {PID} / limits Если вы хотите проверить, сколько файлов открывает процесс, получите его PID, а затем: ls -1 / proc / {PID} / fd | wc -l (обратите внимание, что для ls это «минус один», не путать с «минус el»)
Если вы хотите узнать подробности с помощью lsof, но только для тех файловых обработчиков, которые учитываются в ограничении, попробуйте следующее: lsof -p $ {PID} | grep -P "^ (\ w + \ s +) {3} \ d + \ D +" lsof -p $ {PID} -d '^ cwd, ^ err, ^ ltx, ^ mem, ^ mmap, ^ pd, ^ rtd, ^ txt' -a
Примечание: 'файлы' - это files / pipe / tcp connections / и т. д.
Обратите внимание, что иногда вам, вероятно, понадобится быть root или использовать sudo для получения правильного результата для команд, без привилегий иногда у вас нет ошибки, только меньше результатов.
и, наконец если вы хотите знать, к каким «файлам» в вашей файловой системе обращается процесс, посмотрите: lsof -p {PID} | grep / | awk '{print $ 9}' | сортировать | uniq
веселитесь!