Задать вопрос
Все статьи / Полезная информация / Работа с системными лимитами (ulimit, file descriptors)
Найти результаты:
Период:
с:
 
по:
Помощь в поиске

Помощь в поиске

apple banana
Найти записи, которые содержат хотя бы одно из двух слов.

+apple +juice
Найти записи, которые содержат оба слова.

+apple macintosh
Найти записи, которые содержат слово 'apple', но положение записей выше, если они также содержат 'macintosh'.

+apple -macintosh
Найти записи, которые содержат слово 'apple', но не 'macintosh'.

+apple ~macintosh
Найти записи, которые содержат слово 'apple', но если запись также содержит слово 'macintosh', rate it lower than if row does not. Это более "мягкий" чем поиск '+apple -macintosh', для которого наличие 'macintosh' вызывает что записи не будут возвращены вовсе.

+apple +(>turnover <strudel)
Найти записи, которые содержат слова 'apple' и 'turnover', или 'apple' и 'strudel' (в любом порядке), но ранг 'apple turnover' выше чем 'apple strudel'.

apple*
Найти записи, которые содержат такие слова как 'apple', 'apples', 'applesauce', или 'applet'.

"some words"
Найти записи, которые содержат точную фразу 'some words' (например записи содержащие 'some words of wisdom', но не "some noise words").

Работа с системными лимитами (ulimit, file descriptors)

В процессе эксплуатации Unix‑подобных систем администраторы и разработчики нередко сталкиваются с ограничениями, накладываемыми на ресурсы процессов: числом открытых файлов, размером стека, объемом доступной памяти и т. д. 

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

Что такое системные лимиты в Linux

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

Лимиты действуют на разные типы ресурсов. Среди них – количество открытых файловых дескрипторов, максимальное число процессов, размер стека, объем памяти, размер core dump и другие параметры. Для обычного пользователя эти ограничения часто незаметны, но на сервере с веб-приложениями, базами данных, очередями сообщений или контейнерами они напрямую влияют на стабильность работы.

В Linux обычно различают два вида лимитов:

  • Soft limit – мягкое ограничение. Это текущее значение, с которым работает процесс. Пользователь или приложение могут повысить его самостоятельно, но только до уровня hard limit.
  • Hard limit – жесткое ограничение. Это верхняя граница, выше которой обычный пользователь подняться не может. Изменять hard limit обычно может только root или процесс с нужными привилегиями.

Например, у пользователя может быть soft limit на открытые файлы 1024, а hard limit – 65535. В таком случае процесс по умолчанию сможет открыть до 1024 файловых дескрипторов, но при необходимости лимит можно увеличить до 65535.

Системные лимиты наследуются процессами. Если пользователь запускает shell, а из нее – приложение, то приложение получает ограничения этой shell-сессии. Для сервисов, которые запускаются через systemd, лимиты задаются отдельно: настройки пользовательской сессии на них могут не распространяться.

Главная задача системных лимитов – удерживать баланс между свободой приложения и безопасностью всей системы. Слишком низкие значения приводят к ошибкам вроде Too many open files, а слишком высокие без контроля могут позволить одному процессу исчерпать ресурсы сервера.

Зачем нужны ограничения ресурсов

Ограничения ресурсов в Linux нужны для того, чтобы система оставалась стабильной даже при ошибках в приложениях, резком росте нагрузки или некорректных действиях пользователя. Они задают разумные границы: сколько файлов можно открыть, сколько процессов создать, какой объем памяти использовать, какого размера может быть core dump и так далее.

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

  • Ограничения помогают решать несколько задач:
  • защищают сервер от полного исчерпания ресурсов;
  • снижают риск аварий из-за ошибок в приложениях;
  • не дают одному пользователю повлиять на работу других;
  • помогают контролировать нагрузку в многопользовательских системах;
  • ограничивают последствия атак и некорректных скриптов;
  • делают поведение сервисов более предсказуемым.

Например, лимит на количество процессов (nproc) помогает защититься от ситуаций, когда программа создает слишком много дочерних процессов. Лимит на файловые дескрипторы (nofile) ограничивает число одновременно открытых файлов, сокетов и сетевых соединений. Ограничение размера core dump не позволяет диагностическим файлам занять слишком много места на диске.

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

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

Команда ulimit и ее возможности

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

Например, если изменить лимит открытых файлов через ulimit, а затем запустить приложение из этой же shell-сессии, приложение получит новое значение. Но после выхода из терминала настройка пропадет. Поэтому ulimit чаще используют для быстрой проверки, диагностики и временного тестирования, а постоянные лимиты задают через /etc/security/limits.conf, файлы в /etc/security/limits.d/ или настройки systemd.

Посмотреть все текущие ограничения можно командой:

ulimit -a

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

У каждого лимита может быть два значения:

soft limit – текущее рабочее ограничение;
hard limit – максимальная граница, выше которой обычный пользователь не может поднять soft limit.

Для просмотра soft limit используется ключ -S, для hard limit – -H.

Например:

ulimit -Sn
ulimit -Hn

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

Основные команды ulimit:

Команда Что показывает
ulimit -a Все текущие лимиты сессии
ulimit -n Максимальное количество открытых файловых дескрипторов
ulimit -Sn Soft limit для открытых файлов
ulimit -Hn Hard limit для открытых файлов
ulimit -u Максимальное количество процессов пользователя
ulimit -Su Soft limit на количество процессов
ulimit -Hu Hard limit на количество процессов
ulimit -c Максимальный размер core dump
ulimit -s Размер стека
ulimit -v Максимальный объем виртуальной памяти
ulimit -f Максимальный размер создаваемого файла
ulimit -t Максимальное процессорное время
ulimit -l Максимальный объем памяти, который можно заблокировать в RAM

Работа с системными лимитами особенно актуальна на серверах, где одновременно запущены веб-приложения, базы данных, очереди, контейнеры и фоновые задачи. Используя виртуальные серверы Spaceweb, вы получаете доступ к Linux-среде и можете самостоятельно настраивать ограничения для пользователей, процессов и сервисов. Это помогает поддерживать стабильную работу приложений и заранее снижать риск сбоев при росте нагрузки.

File descriptors и их роль в работе сервисов

File descriptor, или файловый дескриптор, – это числовой идентификатор открытого ресурса внутри процесса Linux. Несмотря на название, речь идет не только о файлах. Через дескрипторы процесс работает с файлами, сетевыми соединениями, сокетами, pipe, устройствами, логами, временными файлами и другими объектами ввода-вывода.

У каждого процесса по умолчанию есть три стандартных дескриптора:

Дескриптор Назначение Описание
0 stdin стандартный ввод
1 stdout стандартный вывод
2 stderr стандартный поток ошибок

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

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

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

Too many open files
EMFILE
accept: Too many open files
socket: Too many open files
open() failed

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

Проверить, сколько дескрипторов открыто у конкретного процесса, можно через /proc:

ls /proc/<PID>/fd | wc -l

А посмотреть лимиты процесса:

cat /proc/<PID>/limits

Для поиска PID сервиса можно использовать:

pidof nginx
pidof postgres
pidof redis-server

Важно смотреть именно лимиты нужного процесса, а не только результат команды ulimit -n в терминале. Shell-сессия и сервис, запущенный через systemd, могут иметь разные ограничения.

File descriptors напрямую связаны с производительностью и доступностью сервиса. Например, если веб-сервер должен обслуживать тысячи одновременных соединений, лимит nofile должен быть выше ожидаемого количества соединений с запасом для логов, файлов, upstream-сокетов и внутренних операций. Для баз данных запас также необходим: кроме клиентских подключений, дескрипторы расходуются на файлы данных, индексы, журналы и временные операции.

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

Настройка лимитов для пользователей

Постоянные лимиты для пользователей обычно задаются в файле:

/etc/security/limits.conf

Также могут использоваться отдельные файлы в каталоге:

/etc/security/limits.d/

Пример настройки:

deploy soft nofile 65535
deploy hard nofile 65535
deploy soft nproc 4096
deploy hard nproc 8192

Формат записи:

<domain> <type> <item> <value>

Где:

  • domain – пользователь, группа или * для всех;
  • type – soft или hard;
  • item – тип лимита;
  • value – значение.

Например, чтобы увеличить лимит открытых файлов для пользователя deploy, можно добавить:

deploy soft nofile 65535
deploy hard nofile 65535

Чаще всего на серверах настраивают следующие параметры:

Параметр Что ограничивает
nofile Количество открытых файловых дескрипторов
nproc Количество процессов пользователя
core Размер core dump
memlock Объем памяти, который можно заблокировать в RAM
fsize Максимальный размер создаваемого файла

Важно, чтобы для применения пользовательских лимитов был подключен модуль PAM:

session required pam_limits.so

Его можно проверить в файлах:

/etc/pam.d/common-session
/etc/pam.d/common-session-noninteractive

В некоторых дистрибутивах расположение может отличаться, но принцип тот же: если pam_limits.so не используется, настройки из limits.conf могут не примениться при входе пользователя.

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

ulimit -n
ulimit -u

Или посмотреть все ограничения сразу:

ulimit -a

Настройка лимитов для процессов

Для сервисов, запущенных через systemd, настройки из limits.conf часто не применяются. Такие процессы получают лимиты от systemd, поэтому их нужно задавать в unit-файле или drop-in конфигурации.

Чтобы создать переопределение для сервиса, пропишите:

sudo systemctl edit nginx

Затем добавьте:

[Service]
LimitNOFILE=65535
LimitNPROC=8192

И выполните:

sudo systemctl daemon-reload
sudo systemctl restart nginx

Проверить лимиты процесса можно с помощью команды:

cat /proc/$(pidof nginx | awk '{print $1}')/limits

Для глобальных настроек systemd используются файлы:

/etc/systemd/system.conf
/etc/systemd/user.conf

Например:

DefaultLimitNOFILE=65535
DefaultLimitNPROC=8192

После изменения глобальных параметров может потребоваться перезагрузка или перезапуск соответствующих сервисов.

Для контейнеров лимиты могут задаваться отдельно. В Docker, например:

docker run --ulimit nofile=65535:65535 nginx
В docker-compose.yml:
services:
  app:
    image: nginx
    ulimits:
      nofile:
        soft: 65535
        hard: 65535

Здесь важно помнить, что контейнер не живет отдельно от хоста. Даже высокие лимиты внутри контейнера не помогут, если ограничения заданы ниже на уровне хостовой системы или рантайма.

Влияние лимитов на производительность серверов

Лимиты напрямую влияют на то, сколько клиентов, файлов, сокетов и рабочих процессов может обслуживать система.

Для веб-сервера низкий nofile ограничивает количество одновременных соединений. Для PostgreSQL или MySQL нехватка дескрипторов может мешать открытию файлов данных и клиентских подключений. Для Redis, RabbitMQ, Kafka и похожих сервисов лимиты особенно заметны при большом числе соединений.

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

Например, для Nginx важны не только системные лимиты, но и параметры: worker_processes auto и worker_connections 4096. 

Максимальное число соединений примерно зависит от произведения worker_processes и worker_connections, но оно не должно превышать доступный лимит файловых дескрипторов.

Для Linux также важен общий системный лимит открытых файлов:

cat /proc/sys/fs/file-max

Текущее использование файловых дескрипторов в системе:

cat /proc/sys/fs/file-nr

Повышение nofile для одного сервиса имеет смысл только после оценки реальной нагрузки. Хорошая практика – смотреть метрики, логи и потребление ресурсов, а не копировать максимальные значения из случайных инструкций.

Типичные ошибки при настройке лимитов

Ошибка Чем опасна Как исправить
Менять ulimit только в терминале Настройка действует только в текущей сессии и пропадает после выхода Для пользователей использовать limits.conf, для сервисов – systemd drop-in
Настраивать limits.confдля systemd-сервиса Сервис может не получить новые значения Задать LimitNOFILE, LimitNPROC в unit-файле
Повышать только soft limit Процесс не сможет подняться выше hard limit Указывать оба значения: soft и hard
Ставить слишком низкий nofile Сервис перестает принимать соединения и открывать файлы Рассчитать лимит с учетом нагрузки и проверить /proc/<PID>/limits
Ставить огромные лимиты без анализа Один процесс может занять слишком много ресурсов Повышать лимиты постепенно и контролировать метрики
Не перезапускать сервис после изменения Старый процесс продолжает работать с прежними лимитами Выполнить daemon-reload и перезапуск сервиса
Проверять лимит только командой ulimit -n Команда показывает лимит текущей shell, а не нужного процесса Смотреть cat /proc/<PID>/limits
Игнорировать контейнерные ограничения Внутри контейнера значения могут отличаться от ожидаемых Настроить ulimits в Docker/Compose и проверить лимиты на хосте
Путать file descriptors и обычные файлы Сокеты и соединения тоже расходуют дескрипторы Учитывать все открытые ресурсы процесса
Не проверять PAM-настройки Лимиты для пользователей могут не применяться Проверить наличие pam_limits.so в PAM-конфигурации

Итоги

Системные лимиты в Linux помогают контролировать использование ресурсов и защищают сервер от перегрузки. Они задают границы для пользователей, shell-сессий, процессов, systemd-сервисов и контейнеров.

ulimit удобен для быстрой проверки и временного изменения ограничений, но для постоянной настройки нужны limits.conf, файлы в limits.d, systemd-параметры или конфигурация контейнерного рантайма.

Предыдущая статья
Протокол SNMP и его использование для мониторинга
Следующая статья
Работа с файлами и каталогами в Linux