- Что такое системные лимиты в Linux
- Зачем нужны ограничения ресурсов
- Команда 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.
Посмотреть все текущие ограничения можно командой:
В выводе будут показаны лимиты на размер core dump, количество открытых файлов, размер стека, число пользовательских процессов и другие параметры.
У каждого лимита может быть два значения:
soft limit – текущее рабочее ограничение;
hard limit – максимальная граница, выше которой обычный пользователь не может поднять soft limit.
Для просмотра soft limit используется ключ -S, для hard limit – -H.
Например:
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-соединение, пишет лог или подключается к базе данных, оно использует файловые дескрипторы.
Веб-серверу нужны дескрипторы для клиентских подключений, файлов сайта, логов и внутренних сокетов. Базе данных – для файлов таблиц, журналов транзакций, временных файлов и соединений с клиентами. Брокеру сообщений – для сетевых подключений, очередей, файлов хранения и служебного обмена.
Если лимит файловых дескрипторов слишком низкий, сервис может работать нормально при небольшой нагрузке, но начать сбоить при росте числа подключений. Типичные ошибки в логах выглядят так:
EMFILE
accept: Too many open files
socket: Too many open files
open() failed
Такие сообщения означают, что процесс достиг разрешенного лимита открытых дескрипторов. После этого он уже не может открыть новый файл, принять очередное соединение или создать новый сокет.
Проверить, сколько дескрипторов открыто у конкретного процесса, можно через /proc:
А посмотреть лимиты процесса:
Для поиска PID сервиса можно использовать:
pidof postgres
pidof redis-server
Важно смотреть именно лимиты нужного процесса, а не только результат команды ulimit -n в терминале. Shell-сессия и сервис, запущенный через systemd, могут иметь разные ограничения.
File descriptors напрямую связаны с производительностью и доступностью сервиса. Например, если веб-сервер должен обслуживать тысячи одновременных соединений, лимит nofile должен быть выше ожидаемого количества соединений с запасом для логов, файлов, upstream-сокетов и внутренних операций. Для баз данных запас также необходим: кроме клиентских подключений, дескрипторы расходуются на файлы данных, индексы, журналы и временные операции.
При этом не стоит бездумно выставлять максимально возможные значения. Высокий лимит разрешает процессу открыть больше ресурсов, но не добавляет серверу память, CPU или сетевую пропускную способность. Если приложение не закрывает файлы или соединения из-за утечки, большой лимит только отложит сбой и усложнит диагностику.
Настройка лимитов для пользователей
Постоянные лимиты для пользователей обычно задаются в файле:
Также могут использоваться отдельные файлы в каталоге:
Пример настройки:
deploy hard nofile 65535
deploy soft nproc 4096
deploy hard nproc 8192
Формат записи:
Где:
- domain – пользователь, группа или * для всех;
- type – soft или hard;
- item – тип лимита;
- value – значение.
Например, чтобы увеличить лимит открытых файлов для пользователя deploy, можно добавить:
deploy hard nofile 65535
Чаще всего на серверах настраивают следующие параметры:
| Параметр | Что ограничивает |
| nofile | Количество открытых файловых дескрипторов |
| nproc | Количество процессов пользователя |
| core | Размер core dump |
| memlock | Объем памяти, который можно заблокировать в RAM |
| fsize | Максимальный размер создаваемого файла |
Важно, чтобы для применения пользовательских лимитов был подключен модуль PAM:
Его можно проверить в файлах:
/etc/pam.d/common-session-noninteractive
В некоторых дистрибутивах расположение может отличаться, но принцип тот же: если pam_limits.so не используется, настройки из limits.conf могут не примениться при входе пользователя.
После изменения лимитов нужно завершить текущую сессию и войти заново. Уже открытый терминал не всегда получит новые значения. Проверить результат можно командой:
ulimit -u
Или посмотреть все ограничения сразу:
Настройка лимитов для процессов
Для сервисов, запущенных через systemd, настройки из limits.conf часто не применяются. Такие процессы получают лимиты от systemd, поэтому их нужно задавать в unit-файле или drop-in конфигурации.
Чтобы создать переопределение для сервиса, пропишите:
Затем добавьте:
LimitNOFILE=65535
LimitNPROC=8192
И выполните:
sudo systemctl restart nginx
Проверить лимиты процесса можно с помощью команды:
cat /proc/$(pidof nginx | awk '{print $1}')/limits
Для глобальных настроек systemd используются файлы:
/etc/systemd/user.conf
Например:
DefaultLimitNPROC=8192
После изменения глобальных параметров может потребоваться перезагрузка или перезапуск соответствующих сервисов.
Для контейнеров лимиты могут задаваться отдельно. В Docker, например:
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 также важен общий системный лимит открытых файлов:
Текущее использование файловых дескрипторов в системе:
Повышение 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-параметры или конфигурация контейнерного рантайма.