Слишком много открытых файловых дескрипторов

Обновлено: 04.07.2024

Я пытаюсь установить 389-ds , и это дает мне это предупреждение:

Я понимаю о файловых дескрипторах, но не понимаю мягких и жестких ограничений.

Когда я бегу cat /proc/sys/fs/file-max , я возвращаюсь 590432 . Это должно подразумевать, что я могу открыть до 590432 файлов (т.е. иметь до 590432 файловых дескрипторов.

Но когда я бегу ulimit , это дает мне разные результаты:

Но каковы жесткие / мягкие ограничения ulimit и как они соотносятся с количеством, хранящимся в /proc/sys/fs/file-max ?

Согласно документации ядра , /proc/sys/file-max это максимальное, общее, глобальное количество файловых дескрипторов, которое ядро ​​выделит перед запуском. Это ограничение ядра, а не вашего текущего пользователя. Таким образом, вы можете открыть 590432 при условии, что вы один в режиме ожидания (однопользовательский режим, демоны не запущены).

Обратите внимание, что документация устарела: файл был proc/sys/fs/file-max в течение длительного времени. Спасибо Martin Jambon за указание на это.

О разнице между мягкими и жесткими пределами можно узнать здесь, на SE . Вы можете повышать или понижать мягкое ограничение как обычный пользователь, при условии, что вы не превышаете жесткое ограничение. Вы также можете снизить жесткий лимит (но вы не можете повысить его снова для этого процесса). Как суперпользователь, вы можете поднимать и опускать как жесткие, так и мягкие ограничения. Схема двойного ограничения используется для обеспечения соблюдения системных политик, но также позволяет обычным пользователям устанавливать временные ограничения для себя, а затем изменять их.

Обратите внимание, что если вы попытаетесь снизить жесткий предел ниже мягкого (и вы не являетесь суперпользователем), вы EINVAL вернетесь (неверный аргумент).

Итак, в вашем конкретном случае ulimit (что совпадает с ulimit -Sf ) говорится, что у вас нет мягкого ограничения на размер файлов, записываемых оболочкой и ее подпроцессами . (это, вероятно, хорошая идея в большинстве случаев)

Ваш другой вызов ulimit -Hn сообщает об -n ограничении (максимальное количество дескрипторов открытых файлов), а не об -f ограничении, поэтому мягкий предел кажется выше жесткого ограничения. Если вы войдете, ulimit -Hf вы также получите «безлимитный».

Я работаю над огромным устаревшим Java-приложением, с большим количеством рукописных материалов, которые в настоящее время вы позволяете фреймворку обрабатывать.

проблема, с которой я сейчас сталкиваюсь, заключается в том, что у нас заканчиваются дескрипторы файлов на нашем сервере Solaris. Я хотел бы знать, какой лучший способ отслеживать открытые дескрипторы файлов? Где посмотреть и что может привести к запуску открытых дескрипторов файлов?

Я не могу отлаживать приложение под Solaris, только в моей среде разработки Windows. IS-IS даже разумно анализировать открытые дескрипторы файлов под Windows?

одна хорошая вещь, которую я нашел для отслеживания незамкнутых дескрипторов файлов, - FindBugs:

Он проверяет много вещей, но одна из самых полезных-операции открытия/закрытия ресурсов. Это программа статического анализа, которая работает на вашем исходном коде, и она также доступна как плагин eclipse.

в windows вы можете посмотреть открытые дескрипторы файлов с помощью process explorer:

на Solaris вы можете использовать "lsof" для мониторинга открытых дескрипторов файлов

Ее стоит иметь в виду, что открытые сокеты также потребляют дескрипторы файлов в системах Unix. Таким образом, это может быть что - то вроде утечки пула соединений с базой данных (например, открытые соединения с базой данных не закрываются и не возвращаются в пул), что приводит к этой проблеме-конечно, я видел эту ошибку раньше, вызванную утечкой пула соединений.

чтобы ответить на вторую часть вопроса:

что может вызвать запуск дескрипторов открытых файлов?

открытие большого количества файлов, очевидно, а затем не закрытие их.

самый простой сценарий заключается в том, что ссылки на любые объекты содержат собственные дескрипторы (например, FileInputStream ) выбрасываются перед закрытием, что означает, что файлы остаются открытыми до завершения объектов.

другой вариант заключается в том, что объекты хранятся где-то и не закрыта. Свалка кучи может сказать вам, что задерживается где ( jmap и jhat включены в JDK, или вы можете использовать jvisualvm если вы хотите GUI). Вы, вероятно, заинтересованы в поиске объектов, владеющих FileDescriptor s.

этот маленький скрипт поможет мне следить за количеством открытых файлов, когда мне нужно проверить количество ic. Если использовался на Linux, то для Solaris его надо латать (может быть :) )

Это может быть непрактично в вашем случае, но то, что я сделал однажды, когда у меня была аналогичная проблема с открытыми подключениями к базе данных, переопределило функцию "open" с моей собственной. (Удобно, что у меня уже была эта функция, потому что мы написали наш собственный пул соединений.) В моей функции я добавил запись в таблицу запись открыта. Я сделал вызов трассировки стека и сохранил идентификацию вызывающего абонента, а также время вызова, и я забыл, что еще. Когда соединение было освобождено, я удалил элемент таблицы. Затем у меня был экран, где мы могли бы сбросить список открытых записей. Затем вы могли посмотреть на отметку времени и легко увидеть, какие соединения были открыты в течение маловероятного количества времени, и какие функции сделали эти открытия.

из этого мы смогли быстро отследить пару функций, которые открывали соединения и не закрывали их.

Если у вас есть много открытых дескрипторов файлов, вероятность того, что вы не сможете закрыть их, когда вы сделано где-то. Вы говорите, что проверили правильность блоков try/finally, но я подозреваю, что где-то в коде вы либо пропустили плохой, либо у вас есть функция, которая передает и никогда не доходит до finally. Я полагаю, также возможно, что вы действительно делаете правильные закрытия каждый раз, когда открываете файл, но вы открываете сотни файлов одновременно. Если это так, я не уверен, что вы можете сделать, кроме серьезного редизайна программы для управления меньшим количеством файлов или серьезной программы редизайн для очереди доступа к файлам. (В этот момент я добавляю обычное: "не зная подробностей вашего заявления и т. д.)

Я бы начал с запроса моего sysadmin, чтобы получить список всех открытых файловых дескрипторов для процесса. Разные системы делают это по-разному: Linux, например, имеет . Я помню, что у Solaris есть команда (возможно pfiles?) это сделает то же самое-ваш сисадмин должен знать это.

однако, если вы не видите много ссылок на один и тот же файл, список fd не поможет вам. Если это серверный процесс, он, вероятно, имеет много файлы (и сокеты) открываются не просто так. Единственный способ решить проблему-настроить системное ограничение на открытые файлы - вы также можете проверить ограничение для каждого пользователя с помощью ограничение, но в большинстве текущих установок это равно системному пределу.

Не прямой ответ на ваш вопрос, но эти проблемы могут быть результатом неправильно выпуская файл ресурсов в код. Например, если вы работаете с классами FileOutputsStream, убедитесь, что методы close вызываются в блоке finally, как в этом примере:

Я бы дважды проверил настройки среды на вашем поле Solaris. Я считаю, что по умолчанию Solaris разрешает только 256 дескрипторов файлов для каждого процесса. Для серверного приложения, особенно если оно работает на выделенном сервере, это очень низко. Рисунок 50 или более дескрипторов для открытия JRE и библиотечных банок, а затем по крайней мере один дескриптор для каждого входящего запроса и запроса базы данных, вероятно, больше, и вы можете видеть, как это просто не сократит горчицу для серьезного сервер.

посмотреть /etc/system file, для значений rlim_fd_cur и rlim_fd_max , чтобы увидеть, что ваша система имеет набор. Затем подумайте, разумно ли это (вы можете увидеть, сколько файловых дескрипторов открыто, пока сервер работает с lsof команда, в идеале с параметром-p [process ID].

Это, безусловно, может дать вам идею. Поскольку это Java, механика открытия/закрытия файла должна быть реализована аналогично (если только одна из JVMs не реализована неправильно). Я бы рекомендовал использовать Файловый Монитор на Windows.

Google для приложения под названием filemon из внутренних систем.

кстати, чтобы отследить это, вы можете использовать что-то вроде aspectj для регистрации всех вызовов, которые открывают и закрывают файлы и регистрируют, где они происходят.

это шаблон кодирования, который помогает найти незакрытые ресурсы. Он закрывает ресурсы, а также жалуется в журнале на проблему.

оберните вышеуказанный файл.close () вызывает блоки try-catch, которые игнорируют ошибки.

кроме того, Java 7 имеет новую функцию "try-with-resource", которая может автоматически закрывать ресурсы.

Если вы работали с программами, которым приходится обрабатывать очень большое количество файловых дескрипторов, например с распределенными базами данных, такими, как Elasticsearch, то вы, наверняка, сталкивались с ошибкой "too many open files в Linux".

Ошибка too many open files Linux

Дословно эта ошибка означает, что программа открыла слишком много файлов и больше ей открывать нельзя. В Linux установлены жёсткие ограничения на количество открываемых файлов для каждого процесса и пользователя.

Посмотреть, сколько файлов можно открыть в вашей файловой системе, можно, выполнив команду:


Посмотреть текущие ограничения количества открытых файлов для пользователя можно командой:


Утилита ulimit возвращает два вида ограничений - hard и soft. Ограничение soft вы можете менять в любую сторону, пока оно не превышает hard. Ограничение hard можно менять только в меньшую сторону от имени обычного пользователя. От имени суперпользователя можно менять оба вида ограничений так, как нужно. По умолчанию отображаются soft-ограничения:

Чтобы вывести hard, используйте опцию -H:

Вы можете изменить ограничение, просто передав в ulimit новое значение:


Но поскольку hard-ограничение составляет 4000, то установить лимит больше этого значения вы не сможете. Чтобы изменить настройки ограничений для пользователя на постоянной основе, нужно настроить файл /etc/security/limits.conf. Синтаксис у него такой:

имя_пользователя тип_ограничения название_ограничения значение

Вместо имени пользователя можно использовать звездочку, чтобы изменения применялись ко всем пользователям в системе. Тип ограничения может быть soft или hard. Название - в нашем случае нужно nofile. И последний пункт - нужное значение. Установим максимум - 1617596.

sudo vi /etc/security/limits.conf

* hard nofile 1617596
* soft nofile 1617596


Нужно установить значение для soft и hard параметра, если вы хотите, чтобы изменения вступили в силу. Также убедитесь, что в файле /etc/pam.d/common-session есть такая строчка:

session required pam_limits.so

Если её нет, добавьте в конец. Она нужна, чтобы ваши ограничения загружались при авторизации пользователя.

Если вам нужно настроить ограничения только для определенного сервиса, например Apache или Elasticsearch, то для этого не обязательно менять все настройки в системе. Вы можете сделать это с помощью systemctl. Просто выполните:

sudo systemctl edit имя_сервиса

И добавьте в открывшейся файл такие строки:

[Service]
LimitNOFILE=1617596
LimitNOFILESoft=1617596


Здесь мы устанавливаем максимально возможное ограничение как для hard- так и для soft-параметра. Дальше нужно закрыть этот файл и обновить конфигурацию сервисов:

sudo systemctl daemon-reload

Затем перезагрузить нужный сервис:

sudo systemctl restart имя_сервиса

Убедится, что для вашего сервиса применились нужные ограничения, можно, открыв файл по пути /proc/pid_сервиса/limits. Сначала смотрим PID нужного нам сервиса:

ps aux | grep elasticsearch


Затем смотрим информацию:


Выводы

В этой небольшой статье мы разобрали, что делать, если возникает ошибка "слишком много открытых файлов Linux", а также как изменять ограничения на количество открытых файлов для пользователя и процесса в Linux.

Анализ и решение Слишком много открытых файлов в Linux

Сегодня в журналах службы появилось большое количество исключений:

Слишком много открытых файлов Эта проблема в основном относится к процессу, пытающемуся открыть файл или дескриптор, но дескриптор, открытый процессом, достиг верхнего предела, и новый дескриптор не может быть открыт.

Как только эта проблема упоминается в Интернете, верхний предел дескриптора должен быть увеличен, и это часто происходит потому, что неправильное использование дескриптора можно назвать утечкой дескриптора. Причина поиска дескриптора для достижения верхнего предела является главной.

Ниже приведено введение в дескрипторы в Linux

Для этих дескрипторов в Linux имеется ограниченное количество, максимальное количество дескрипторов, которые отдельный процесс может открыть по умолчанию, вы можете использовать следующую команду для просмотра:

Результаты приведены ниже:



Одним из открытых файлов является число дескрипторов по умолчанию, в настоящее время количество дескрипторов по умолчанию равно 1024.

Вы также можете установить верхний предел количества дескрипторов процесса.

Результаты приведены ниже:



Также посмотрите на открытые файлы, вы можете увидеть, что верхний предел дескриптора процесса составляет 1024

Количество дескрипторов можно изменить. Чтобы изменить количество дескрипторов по умолчанию, введите следующую команду:

Эта команда может изменить количество дескрипторов по умолчанию на 2000, но значение по умолчанию будет восстановлено после перезапуска системы

Значение по умолчанию этого файла в системе настраивается в файле /etc/security/limits.conf, и добавляется следующая конфигурация:

Жесткая настройка - это фактическое значение по умолчанию, которое является верхним пределом, а мягкая конфигурация используется только для предупреждения. Если мягкое значение будет превышено, появится предупреждение, а третья конфигурация с короткой горизонтальной линией - жесткая. Настраивается одновременно как софт.

Давайте посмотрим, как запросить количество дескрипторов, занятых процессами в системе

Команда lsof - это команда системного мониторинга в Linux. Она может просматривать файлы и порты, открытые процессом. Она мощная. Приведенная выше команда сохраняет количество дескрипторов и PID только после прохождения через серию каналов. Результаты выполнения следующие:



Первый столбец - количество дескрипторов, второй столбец - идентификатор процесса.

Можно видеть, что число дескрипторов первых двух процессов превысило верхний предел, что является исключением из верхней части статьи, о которой сообщают журналы этих двух процессов.

Следующий запрос, какие ручки заняты процессом

Например, чтобы запросить процесс с PID 25950, используется команда

Результаты приведены ниже:



Здесь часть перехвата, смысл каждого столбца следующий:

3. Владелец процесса

4. Файловый дескриптор

Существует несколько типов файлов:

DIR: указывает на каталог.

CHR: указывает тип символа.

BLK: блочный тип устройства.

UNIX: доменный сокет UNIX.

FIFO: очередь первым пришел - первым вышел (FIFO).

IPv4: сокет интернет-протокола (IP).

УСТРОЙСТВО: Укажите название диска

РАЗМЕР: размер файла

NODE: Inode (идентификация файлов на диске)

NAME: точное имя открываемого файла

В процессе, который я рассмотрел, было открыто необычно большое количество файлов типа IPv4, которые можно использовать в качестве подсказки для анализа причины конкретного переполнения дескриптора. В первом примере статьи это произошло потому, что программа продолжала инициировать соединение с другим сервером, что приводило к тому, что дескриптор превышал верхний предел (который также можно анализировать из информации об исключении).

Интеллектуальная рекомендация


Michael.W Поговорите о Hyperledger Fabric. Проблема 20 - Подробная индивидуальная сортировка узла с пятью порядками с исходным кодом для чтения.

Michael.W Поговорите о Hyperledger Fabric. Проблема 20 - Подробная индивидуальная сортировка узла с пятью порядками с исходным кодом чтения Fabric Файл исходного кода одиночного режима находится в ord.


Мяу Пасс Матрица SDUT

Мяу Пасс Матрица SDUT Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description Лянцзян получил матрицу, но эта матрица была особенно уродливой, и Лянцзян испытал отвращение. Чт.


Гессенская легкая двоичная структура удаленного вызова

Hessian - это легкая двоичная структура удаленного вызова, официальный адрес документа, в основном он включает протокол удаленного вызова Hessian, протокол сериализации Hessian, прокси-сервер клиента .


TCP Pasket и распаковка и Нетти Solutions

Основные введение TCP является ориентированным на соединение, обеспечивая высокую надежность услуг. На обоих концах (клиенты и терминалы сервера) должны иметь один или более гнезда, так что передающий.

Читайте также: