Почему (или как) делает количество открытых дескрипторов файлов, используемых корнем, превышают ulimit-n?

возможно, это может работать на Вас...

убийство bittorrent

http://github.com/lg/murder/blob/master/README.md

13
задан 16 July 2012 в 17:08
6 ответов

Ulimit предназначен для дескрипторов файлов. Это применимо к файлам, каталогам, сокетам, epolls каналов, eventfds, timerfds и т. Д.

В любой момент во время запуска процесса ограничения могли быть изменены. Посетите / proc / / limits и посмотрите, не были ли изменены значения.

3
ответ дан 2 December 2019 в 21:26

Похоже, вы рассуждали примерно так: «Я должен снизить этот предел, чтобы у меня не закончились драгоценные дескрипторы». На самом деле все обстоит с точностью до наоборот - если на вашем сервере закончились файловые дескрипторы, вам нужно поднять этот предел с 1024 до большего. Для реалистичной реализации Glassfish разумно 32 768.

Лично я всегда увеличиваю лимит до 8 192 для всей системы - 1024 просто смешно. Но вы захотите поднять стеклянную рыбу выше. Проверьте /etc/security/limits.conf . Вы можете добавить специальную запись для пользователя glassfish , который работает как.

0
ответ дан 2 December 2019 в 21:26

Вы хотите взглянуть на общесистемные ограничения, установленные в / proc / sys / fs / file-max и настройте его там (до следующей перезагрузки) или установите fs.file-max в sysctl.conf, чтобы сделать его постоянным. Это может быть полезно - http://www.randombugs.com/linux/tuning-file-descriptors-limits-on-linux.html

0
ответ дан 2 December 2019 в 21:26

Я тестировал это в 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: слишком много открытых файлов в журналах процессов)

9
ответ дан 2 December 2019 в 21:26

@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 .

    3
    ответ дан 2 December 2019 в 21:26

    Распространенная ошибка при сравнении результата необработанного вызова 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

    веселитесь!

    0
    ответ дан 2 December 2019 в 21:26

    Теги

    Похожие вопросы