Если сайт вдруг начал огрызаться ошибкой «Resource temporarily unavailable», в логах мелькнуло «cannot fork», а поддержка ответила, что вы «упёрлись в лимит процессов»: чаще всего это nproc. Это ограничение не на память и не на скорость процессора, а на само число процессов и потоков, которые ваш аккаунт может держать запущенными в один момент. Пока в бюджете есть место, всё идёт как обычно. Как только он забит, следующий процесс просто не стартует: страница недорисовывается, cron молча пропускает задачу, консоль отказывается открывать новую сессию.
Проверить, в этом ли причина, можно там же, где смотрят остальные лимиты. В cPanel это раздел «Resource Usage», строка с числом процессов (её подписывают nproc или «Number of Processes»). Стоят напротив faults, то есть срабатывания лимита, и гадать больше не о чем. Отличить эту историю от упора в процессор проще всего по одному признаку: при нехватке CPU сайт обычно замедляется, но продолжает отвечать, а при упоре в nproc процесс вообще не создаётся, и вместо медленной страницы вы получаете оборванную или ошибку.
Ниже разберём, почему этот потолок вообще существует, чем отличается от двух соседних лимитов (их постоянно смешивают в один), что его на самом деле забивает и почему поднять цифру помогает не всегда.
Что такое nproc и почему это не про мощность
nproc – это счётчик, и считает он не мегабайты и не проценты ядра, а штуки: сколько отдельных процессов и потоков крутится под вашим аккаунтом прямо сейчас. Такой потолок есть у каждого аккаунта на виртуальном хостинге, даже если в тарифе про него ни слова. Универсального числа нет: сам CloudLinux в рекомендациях для типового shared-аккаунта ставит nproc=100, для мощного тарифа держит то же значение и лишь разводит верхнюю планку по посетителям, а конкретный хостер выставляет своё, нередко выше.
Ключевое здесь в том, что в этот счётчик валится всё сразу, а не только «сайт». PHP собирает страницу – это процессы. Отработал cron, плюс процесс, а то и несколько. Зашли по SSH, ещё один. Полез бэкап архивировать базу, снова. Все они делят один и тот же бюджет, и когда он кончается, операционная система отвечает на попытку создать новый процесс коротким отказом. На уровне PHP это оборванная генерация страницы, на уровне консоли – то самое «-bash: fork: retry: Resource temporarily unavailable».
Откуда берётся этот потолок и почему он выглядит именно так, проще всего понять через CloudLinux – систему, которая на большинстве виртуальных хостингов режет сервер на изолированные доли и выдаёт каждому аккаунту свою квоту по памяти, процессору и числу процессов. nproc – одна из этих квот, соседняя с теми, что вы, возможно, уже встречали. Если нужна общая карта всех лимитов аккаунта и того, как они связаны, она собрана в отдельном разборе.
Сбивает с толку тут единица измерения. Память меряют в мегабайтах, это привычно и наглядно. А nproc считает процессы, которых обычный владелец сайта не видит и руками не создаёт: они появляются и исчезают сами, десятками в секунду, и «сколько их сейчас» – вопрос, на который без панели не ответишь.
Три стенки, которые все называют «процессами»
Вот место, ради которого и стоило заводить отдельную статью. На виртуальном хостинге есть три разных ограничения, и в разговоре их все зовут «процессами» или «нагрузкой», отчего в голове они слипаются в одно. А устроены они по-разному, ведут себя по-разному и лечатся по-разному.
Первое – лимит процессора. Он про скорость: сколько процессорного времени вам разрешено сжечь. Упёрлись: приложению достаётся меньше процессорного времени, и оно начинает отвечать медленнее; чаще всего сайт при этом не падает, а тормозит. Симптом – задержки, которые растут вместе с посещаемостью.
Второе – Entry Processes (EP). Он считает входы в вашу изолированную среду: сколько запросов одновременно «зашло» на обработку в данный момент. Обычно это веб-запросы: почти каждое обращение к PHP-странице создаёт один такой вход, но живёт он доли секунды и тут же освобождается. Пробили этот потолок – сервер отдаёт 508 «Resource Limit Reached». Симптом – часть посетителей ловит 508 в момент наплыва, остальным нормально.
Третье – nproc, ему и посвящён текст. Он считает не входы, а вообще все процессы и потоки внутри аккаунта: и веб-обработчики, и то, что они порождают уже внутри, и cron, и SSH-сессии, и потоки. Пробили – новый процесс не создаётся, fork не проходит, а посетитель может получить 500 или 503.
Разница между EP и nproc тонкая, и именно на ней рассуждение чаще всего сворачивает не туда. EP считает только входы извне: пришёл запрос – плюс один вход, отработал – минус. А всё, что процесс запускает уже внутри аккаунта (дамп базы, отправку письма, обращение к MySQL), нового входа не создаёт, EP не растёт, зато число процессов в nproc увеличивается. Добавьте сюда потоки, которых EP не видит вовсе. Поэтому nproc на хостинге всегда ставят выше EP: CloudLinux прямо рекомендует держать его как минимум на 15 больше. Из этого и рождается фирменная жалоба: «по EP в панели тишина, свободно, а процесс всё равно не создаётся». Значит, вы упёрлись не в EP, а в общий бюджет nproc, и набили его не входящие посетители, а то, что крутится внутри. Обратный случай обиднее: подняли EP по совету поддержки, а «cannot fork» никуда не делся, потому что лечили не ту стенку.
Кстати, у фоновых задач вроде cron и бэкапов есть противная привычка ломаться молча. Веб-запрос, которому не хватило процесса, хотя бы отдаст видимую ошибку в браузер. А ночная задача, упёршаяся в тот же потолок, просто не выполнится, и вы узнаете об этом не в момент сбоя, а когда однажды полезете за бэкапом и обнаружите, что за последнюю неделю его нет.
Потоки считаются так же, как процессы
Раздел короткий, но пропускать его не стоит: про это почти никто не думает.
Счётчик nproc считает не только процессы, но и потоки внутри них. Один процесс, который внутри себя держит двадцать потоков, способен занять из бюджета не единицу, а близко к двадцати: считается каждый поток, реально запущенный внутри аккаунта. Для обычного PHP это редко проблема, но стоит на сайте появиться чему-то многопоточному (обработке картинок через ImageMagick, headless-браузеру для генерации превью, тяжёлой библиотеке импорта), и один такой запрос способен в одиночку отъесть заметную долю лимита.
Выглядит это обманчиво. По числу процессов в привычном понимании у вас всё скромно, пара десятков, а счётчик nproc почему-то полон. Причина ровно в том, что за одним видимым процессом стоит пучок потоков, и в бюджет идёт каждый. Хостер при этом видит всплеск числа процессов там, где по логам сайта всего один тяжёлый запрос, и это сбивает с толку уже обе стороны.
Что на живом сайте забивает этот лимит
Список виновников из практики довольно короткий и от сайта к сайту повторяется.
Разогнавшийся wp-cron. На WordPress планировщик по умолчанию срабатывает на визитах, а не по часам: подошло время события, и его запускает первый же зашедший посетитель. При хорошей посещаемости таких запусков набегает много, и в пик они умеют забрать заметную часть бюджета. Не каждый визит плодит отдельный параллельный процесс, но при плотном трафике и тяжёлых задачах наложений хватает.
Бэкап – классика жанра, CloudLinux даже приводит его как типовой пример, когда число процессов внезапно подскакивает. Снимая копию, такой плагин обычно запускает дополнительные и долгие фоновые задачи – архивацию файлов, дамп базы, иногда выгрузку в облако; сколько именно процессов и как они устроены, зависит от конкретного плагина. Вдобавок архивация даёт шквал обращений к диску, а у диска свои отдельные потолки: на число операций в секунду (IOPS) и на скорость чтения-записи (bandwidth), так что тяжёлый ночной бэкап нередко упирается сразу в несколько стенок. Пока копия снимается на живом сайте под трафиком, всё это ложится поверх обычной нагрузки. Наблюдение, которое всплывает постоянно: сайт «падает» каждую ночь в одно и то же время, а это не атака, а собственный бэкап по расписанию.
Фоновые задачи и внешние интеграции. Скрипт, который шлёт уведомления или синхронизируется со сторонним API, нередко делает это в несколько параллельных процессов, и на массовой рассылке это хорошо заметно. Сюда же – оборванная SSH-консоль, которая иногда оставляет за собой висящий процесс; источник не главный, зато бесплатный к проверке.
Что объединяет весь список: почти всё это фон, а не посетители. Оттого упор в nproc так часто случается в самый тихий по трафику момент, глухой ночью, и владелец в первую очередь думает на что угодно, только не на собственные фоновые задачи.
Как это выглядит и с чем путают
Сигнатур у проблемы немного, и узнавать их в лицо полезно. В консоли – «fork: retry: Resource temporarily unavailable» или короткое «cannot fork». В логах PHP – обрывы генерации, иногда голая 500-я без внятной причины в самом коде. В панели – faults по строке с числом процессов.
Стоит держать в голове, что «cannot fork» указывает на упор в число процессов, но сам по себе стопроцентным диагнозом не служит: та же ошибка EAGAIN возникает и при исчерпании общесистемных потолков, вроде максимума потоков на всю машину. На виртуальном хостинге под CloudLinux это чаще всего именно ваш nproc, и решает дело не текст ошибки, а faults в панели.
Путают это чаще всего с двумя вещами. Первая – нехватка памяти, потому что снаружи похоже: страница оборвалась, отдаётся 500-я или белый экран. Но память, когда кончается, оставляет в логе внятный след «Allowed memory size exhausted», а упор в nproc – след про fork. Если по счётчику памяти до потолка далеко, а страницы всё равно рвутся, смотреть надо на число процессов.
Вторая – 508-я. Это не персональный код EP, а общий сигнал «достигнут лимит ресурсов» в LVE, поэтому по одному только 508 причину не назвать. Разбираться надо по faults: срабатывания по EP означают EP, по числу процессов – nproc, по CPU – процессор, по памяти – PMEM. CloudLinux ведёт отдельный счётчик на каждый ресурс, и именно он, а не код ошибки в браузере, показывает, в какую стенку вы упёрлись. Подробнее про сами коды – в разборе ответов HTTP.
Зачем провайдер держит nproc низким
Со стороны клиента низкий лимит на число процессов выглядит мелочной жадностью: ну что провайдеру стоит разрешить на сотню процессов больше. Со стороны сервера картина другая, и логика тут жёсткая.
Одно из практических назначений этого лимита – не дать одному аккаунту бесконтрольно плодить процессы; сам CloudLinux так и объясняет смысл nproc: чтобы процесс внутри аккаунта не наплодил слишком много подпроцессов. Ошибка в коде, кривой плагин, соседний аккаунт под взломом – любой из них способен начать размножать процессы по нарастающей. Не будь потолка, один такой аккаунт рисковал бы утащить за собой ресурсы всей ноды, а на ней живут ещё десятки чужих сайтов. nproc – это предохранитель, который придерживает один аккаунт, чтобы не пострадали остальные.
Со своей стороны провайдер видит то же, что и вы, только раньше и в цифрах: на мониторинге аккаунт упирается в потолок процессов, капают faults. «Оптимизируйте нагрузку» для него не отписка, а буквально то, что показывает панель. По сути обе стороны смотрят на один график, просто с разных концов.
И, как в истории с процессором, цифру nproc часто не выносят в тариф на видное место. Причина прагматичная, ровно та же, по которой неохотно говорят про inode: покажешь параметр, которого нет у конкурентов, и половина обращений в поддержку будет про то, как его поднять, а не про то, почему он забился. Проще не показывать.
Что с этим делать – и почему прибавить число помогает не всегда
Дальше начинается место, где хочется простого ответа «поднимите лимит». Иногда это и правда решение. Но чаще упор в nproc – не про то, что бюджета мало, а про то, что его кто-то бесконтрольно ест, и тогда прибавка просто отодвигает потолок на пару недель.
Начать стоит с faults по числу процессов за неделю, а не с мгновенной цифры – это, пожалуй, главный диагностический шаг во всей истории. Мгновенное значение почти всегда невысокое, вы же смотрите в спокойный момент. А вот регулярные пики faults в одни и те же часы, особенно ночные, показывают, что именно и когда забивает бюджет. Оговорка важная: faults=0 за сегодня не значит, что сайт здоров: возможно, вы просто не попали на окно, когда отрабатывает тяжёлая задача.
Дальше по убыванию частоты случаев. Перевести wp-cron на настоящее серверное расписание: это снимает главный источник наложений, задачи идут по часам, а не толпятся на визитах. Побочек почти нет, помогает почти всегда. Разобраться с бэкапом: перенести снятие копии на серверный уровень или хотя бы развести его по времени с пиками, вместо того чтобы архивировать живой сайт под трафиком; часто одно это убирает ночные «падения». Прибрать зависшее: закрытые, но не завершившиеся SSH-сессии и подвисшие процессы иногда занимают ощутимую долю бюджета, их видно в панели, и начинать удобно с них, потому что это ничего не стоит.
Поднять лимит – законный ход, если сайту действительно нужно больше процессов, но только после того, как вы убедились, что бюджет ест дело, а не разогнавшийся плагин. Иначе это плата за то, чтобы не разбираться, и следующий потолок вы пробьёте так же. И прежде чем доплачивать, полезно понять за что: следующая ступень тарифа не всегда даёт пропорционально больше, а индекс ценности тарифа (TVI) как раз про то, сколько ресурса приходится на каждую гривну. Уйти на VPS имеет смысл сайту, которому реально тесно в рамках общего хостинга, но будто «там лимитов нет» – это миф: и на своём сервере есть свои потолки, от системного RLIMIT_NPROC и ограничений systemd с cgroups до pm.max_children у пула PHP-FPM. Разница в том, что этими потолками управляете вы, а ресурсы машины выделены вам, а не делятся с соседом. Чем VPS на практике отличается от общего хостинга и облака, если смотреть не на строчки тарифа, разобрано в отдельной статье.
Свободная память при рваных страницах сама по себе уже половина диагноза: раз память ни при чём, значит, кончились не байты, а места под процессы. И доедает их, как правило, не наплыв посетителей, а что-то своё, фоновое, работающее по расписанию.
Источники
- CloudLinux OS, раздел «Limits» – официальная документация по лимитам LVE (NPROC, EP, PMEM, CPU), правило «NPROC должен быть больше EP + 15» и поведение при исчерпании (500/503): docs.cloudlinux.com/cloudlinuxos/limits
- CloudLinux, «EP and NPROC limits – a look from inside» – почему входящие процессы увеличивают EP, а порождённые внутри LVE и потоки идут только в NPROC, из-за чего NPROC ставят выше EP: cloudlinux.zendesk.com – EP and NPROC limits
- man7.org, fork(2) – системный вызов fork и ошибка EAGAIN «Resource temporarily unavailable», в том числе при исчерпании лимита на число процессов: man7.org/linux/man-pages/man2/fork.2.html
- PHP, «FPM Configuration» – как менеджер процессов php-fpm (директивы pm, pm.max_children) держит пул воркеров, обслуживающих запросы: php.net/manual/en/install.fpm.configuration.php
- cPanel, «Resource Usage» – как открыть раздел, читать графики использования и находить faults по каждому ресурсу, включая число процессов: kb.hosting.com/docs/latest-visitors-bandwidth-resource-usage
FAQ по nproc
Что значит ошибка «cannot fork» или «Resource temporarily unavailable»?
Это значит, что аккаунт упёрся в лимит на число процессов, nproc, и система отказалась создавать новый процесс. Память и место на диске тут ни при чём: кончился бюджет на количество одновременно запущенных процессов и потоков. Пока он полон, любая попытка запустить ещё один процесс, будь то PHP, cron или консоль, отбивается этим отказом.
Чем лимит nproc отличается от лимита CPU?
CPU ограничивает скорость: сколько процессорного времени вам дают, а nproc – количество процессов и потоков. При упоре в CPU сайт обычно замедляется, но продолжает отвечать, запросы просто встают в очередь. При упоре в nproc новый процесс не создаётся вовсе, и вместо медленной страницы вы получаете оборванную или ошибку. Это две разные стенки, и упереться можно в любую по отдельности.
Чем nproc отличается от EP (Entry Processes)?
EP считает входы в вашу изолированную среду – сколько запросов одновременно на ней обрабатывается. Nproc считает вообще все процессы и потоки внутри, включая те, что уже запущенный процесс порождает сам (дамп базы, отправка почты), и потоки, которых EP не видит. Из-за этого nproc всегда ставят выше EP, и упереться в него можно, когда по EP ещё есть запас: тогда по EP в панели тишина, а процесс всё равно не создаётся.
Считаются ли потоки в лимит процессов?
Да, nproc считает и процессы, и потоки внутри них. Один процесс с двадцатью потоками способен занять из бюджета близко к двадцати единицам, а не одну. Поэтому что-то многопоточное, вроде обработки картинок через ImageMagick или headless-браузера, может в одиночку отъесть заметную долю лимита, хотя «процесс» вроде бы один.
Почему сайт отдаёт ошибку, хотя памяти хватает?
Потому что упор в nproc и нехватка памяти – разные вещи, а снаружи похожи: и там и там страница рвётся или отдаётся 500-я. Разница в логах: нехватка памяти оставляет след «Allowed memory size exhausted», а упор в nproc – след про fork. Если по счётчику памяти до потолка далеко, а страницы всё равно рвутся, смотреть надо на число процессов.
Что вообще забивает nproc на обычном сайте?
Чаще всего это фон, а не посетители: разогнавшийся wp-cron, бэкап, зависшие SSH-сессии, почтовая очередь и синхронизация со сторонними API. Все они делят один бюджет с генерацией страниц. Оттого упор в nproc нередко случается в самый тихий по трафику момент, ночью.
Считаются ли cron и SSH-сессии в лимит процессов?
Да, и то и другое считается в nproc. Cron, отрабатывающий ночью без единого посетителя, и открытая SSH-сессия занимают процессы из общего бюджета аккаунта. При этом входящий счётчик EP они, как правило, не увеличивают, поэтому и получается, что nproc набивается тем, чего по EP не видно.
Как проверить, упёрся ли аккаунт в nproc?
В cPanel это раздел «Resource Usage», строка с числом процессов (её подписывают nproc или «Number of Processes»). Смотреть надо не на мгновенную цифру, а на график за неделю с отметками faults: регулярные срабатывания в одни и те же часы и есть диагноз. При этом faults=0 за сегодня ещё не значит, что сайт здоров – возможно, вы просто не попали на окно тяжёлой задачи.
Что такое faults по nproc и опасны ли они?
Faults – это счётчик срабатываний лимита: сколько раз система отказала аккаунту в создании нового процесса. Единичные faults не страшны, а вот регулярные пики в одни и те же часы означают, что бюджета процессов кому-то стабильно не хватает. Отсутствие faults за короткий отрезок гарантией здоровья не является: тяжёлая задача могла просто не попасть в окно наблюдения.
Поможет ли поднять тариф, если сайт упирается в nproc?
Иногда да, но чаще упор в nproc – не про то, что бюджета мало, а про то, что его кто-то бесконтрольно ест. Если поднять лимит, не разобравшись с причиной, вы просто отодвинете потолок на пару недель и заплатите за то, чтобы не разбираться. Сначала стоит убедиться по faults, что процессы забивает дело, а не разогнавшийся плагин или бэкап.
Почему числа nproc нет в описании тарифа?
По той же причине, по которой неохотно показывают inode и лимит CPU: параметр витрину не украшает, а вопросов от клиентов добавляет. Стоит выставить цифру на видное место, и половина обращений в поддержку будет про то, как её поднять. Лимит при этом никуда не девается – он просто живёт на уровне сервера, а не в вашей панели.
Как быстро разгрузить nproc, не меняя тариф?
Самое результативное – перевести wp-cron с запуска на визитах на настоящее серверное расписание, чтобы задачи не толпились. Дальше – развести бэкап по времени с пиками или перенести его на серверный уровень, а не архивировать живой сайт под трафиком. И прибрать зависшее: закрытые, но не завершившиеся SSH-сессии и подвисшие процессы видно в панели, и убрать их ничего не стоит.
