Шаред-хостинг молча режет процессы: как понять, что дело не в вашем коде
Процесс работал час, два, десять — и вдруг оборвался. В логе приложения тишина: ни исключения, ни стектрейса, ни знакомого сообщения об ошибке, просто последняя строка обрывается на середине, а дальше ничего. Разработчик садится перечитывать свой код в поисках утечки памяти или бесконечного цикла, тратит на это вечер, иногда несколько дней — а причина всё это время была не в коде, а в том, что шаред-хостинг сам принудительно убил процесс, потому что тот вышел за невидимую квоту. Разберём, как отличить одно от другого, не теряя времени на дебаг чужой проблемы.
Содержание
- Почему хостинг режет процессы молча, а не с понятной ошибкой
- Четыре типа лимитов, из-за которых процесс обрывается
- Признак первый: нет характерного паттерна ошибки в собственных логах
- Признак второй: падения коррелируют с нагрузкой, а не с действием пользователя
- Признак третий: у хостера есть отдельные системные логи, которых вы не видите
- Прежде чем часами дебажить код: спросите поддержку хостинга напрямую
Почему хостинг режет процессы молча, а не с понятной ошибкой
Экономика шаред-хостинга держится на переподписке: на одном физическом сервере живут сотни аккаунтов, и тариф в 200-300 рублей окупается только потому, что не все клиенты одновременно грузят CPU и память на полную. Как только один аккаунт начинает вести себя «прожорливо» — держит долгий процесс, открывает много одновременных соединений, съедает память быстрее соседей — хостинг обязан его остановить, иначе пострадают все остальные на этом сервере. Это не произвол конкретного провайдера, а условие, без которого модель шаред-хостинга вообще не работает.
Молчаливость этого механизма — не недосмотр, а следствие того, как устроено принудительное завершение процесса на уровне операционной системы. Когда cgroup или CloudLinux LVE решает, что аккаунт вышел за лимит по памяти или CPU-времени, системе не до того, чтобы вежливо попросить процесс завершиться и дать ему время красиво залогировать причину — она отправляет сигнал SIGKILL, который процесс не может ни перехватить, ни обработать, ни записать в свой лог. Процесс просто исчезает в момент получения сигнала, ровно посреди того, что делал. Отсюда и ощущение «оборвался без причины»: причина была, но она находится не в вашем приложении, а снаружи него, и обычный try/catch или обработчик исключений её в принципе не увидит — тот же механизм разбирается в статье как ядро Linux выбирает, какой процесс убить, и логика OOM killer'а на изолированном cgroup-слайсе шаред-аккаунта работает по тем же правилам, что и на целой машине.
Есть и вторая причина, менее техническая. Хостеру невыгодно публично называть точные цифры лимитов: конкретное число легко превратить в маркетинговый аргумент против него («у нас CPU-лимит выше, переходите к нам»), а расплывчатая формулировка «fair usage» в Acceptable Use Policy защищает провайдера от претензий гораздо лучше, чем жёсткая цифра в договоре. Поэтому даже там, где лимит формально существует и стабильно применяется, узнать его заранее из документации почти никогда не получается — только через факт срабатывания или через прямой вопрос в поддержку.
Четыре типа лимитов, из-за которых процесс обрывается
За фразой «хостинг что-то ограничивает» на практике скрывается несколько разных механизмов, и они выглядят по-разному со стороны приложения.
| Тип лимита | Что происходит технически | Как это выглядит для вас |
|---|---|---|
| Process killer / OOM по памяти | cgroup memory.max (или LVE) превышен, ядро убивает процесс сигналом SIGKILL | Процесс просто исчезает; если оболочка перехватывает код выхода — часто 137; в логе приложения нет финальной записи |
| Лимит CPU-времени | ulimit -t или LVE CPU-квота: процессу выделено ограниченное процессорное время, дальше — принудительное завершение | Долгий скрипт (импорт, генерация отчёта, батч-обработка) обрывается примерно на одном и том же этапе по времени, а не по объёму данных |
| Лимит памяти на процесс | Внутренний лимит интерпретатора (например, PHP memory_limit) — это не то же самое, что внешний cgroup memory.max | Может дать вменяемую ошибку («Allowed memory size exhausted») — это как раз пример того, когда причина видна; отличать от «внешнего» лимита важно, чтобы не путать разные слои |
| Лимит числа процессов / соединений | ulimit -u, cgroup pids.max, PHP-FPM pm.max_children, Apache MaxClients, лимит подключений к БД (max_user_connections) | «fork failed», часть запросов вообще не долетает до приложения, очередь заданий выполняется частично |
Важный нюанс: третья строка таблицы — единственная, где обычно есть внятное сообщение, потому что это лимит внутри самого интерпретатора, а не внешнее принудительное убийство. Остальные три — про то, что вашему процессу просто перестают давать ресурс или обрывают его снаружи, и никакого штатного способа красиво об этом написать в собственный лог у него нет. Реальный пример четвёртой строки — история, когда лимит nproc на пользователя обрубил деплой ровно на середине флота серверов: каждый отдельный шаг деплоя выглядел логично, ошибка проявлялась только в совокупности, когда параллельных процессов становилось слишком много одновременно.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPSПризнак первый: нет характерного паттерна ошибки в собственных логах
Баг в вашем коде почти всегда оставляет след определённой формы: исключение с конкретным типом и сообщением, стектрейс с номером строки, воспроизводимость на одних и тех же входных данных, соответствие формату ошибок, которые генерирует сам фреймворк или библиотека. Если вы используете Sentry, Bugsnag или просто структурированный error_log, у бага обычно есть «подпись» — повторяющийся паттерн, который можно нагуглить или сопоставить со строкой кода.
Принудительное завершение процесса хостингом выглядит принципиально иначе:
- в логе приложения — обрыв последней строки без штатного завершения записи (например, JSON-объект логов не закрыт скобкой, буфер не сброшен);
- нет соответствующего исключения ни в одном из уровней (приложение, веб-сервер, PHP-FPM/uwsgi лог) — просто пустота на месте ожидаемой ошибки;
- в access-логе веб-сервера на этот момент может быть
502/504от прокси перед приложением или просто оборванное соединение — сам бэкенд ничего не успел ответить; - если процесс запускался вручную или через cron, в терминале/выводе может остаться голое слово «Killed» и код выхода 137 — это прямое указание на
SIGKILL, а не на исключение внутри программы.
Практическая проверка: возьмите точное время последнего инцидента и посмотрите, есть ли ровно в этот момент запись об ошибке хоть в одном из ваших логов — приложения, веб-сервера, воркера очереди. Если везде тишина ровно на границе обрыва — это гораздо больше похоже на внешнее убийство процесса, чем на необработанное исключение, которое чаще всего хоть что-то, да оставляет.
Признак второй: падения коррелируют с нагрузкой, а не с действием пользователя
Баг в коде обычно привязан к конкретному действию: определённый запрос, определённые входные данные, конкретная последовательность шагов пользователя. Если вы можете стабильно воспроизвести падение одним и тем же сценарием независимо от времени суток и загрузки сервера — это, вероятнее всего, действительно баг, и лимиты тут ни при чём.
Лимиты хостинга ведут себя иначе — они коррелируют не с тем, *что* делает пользователь, а с тем, *сколько всего* происходит одновременно:
- падения учащаются в часы пиковой посещаемости, а в спокойные ночные часы то же самое действие проходит без проблем;
- инцидент совпадает по времени с фоновой задачей — cron-джобом, импортом, резервным копированием, которые молча добавляют нагрузку поверх обычного трафика;
- на аккаунте несколько сайтов или приложений, и падает не обязательно тот, который в этот момент активно используют — потому что лимит общий на весь аккаунт, а не на конкретный процесс;
- проблема «плавает»: сегодня падает при 50 одновременных пользователях, завтра — при 80, потому что сама доступная квота на переподписанном сервере тоже не константа.
Практическая проверка — наложить временную шкалу инцидентов на график посещаемости (из Яндекс.Метрики или встроенной статистики хостинга) и на список активных cron-заданий. Если падения кучкуются вокруг пиков трафика или совпадают с фоновыми задачами независимо от того, какой конкретно пользователь и что делал в этот момент — это сильный сигнал в сторону внешнего лимита, а не бага в конкретной ветке кода.
Признак третий: у хостера есть отдельные системные логи, которых вы не видите
Ключевая асимметрия шаред-хостинга в том, что факт принудительного убийства процесса кем-то зафиксирован — просто не вами. dmesg и системный журнал ядра на шаред-аккаунте, как правило, недоступны: permission denied при попытке их прочитать — это нормальное поведение, потому что ядро принадлежит физическому серверу и всем его клиентам сразу, а не конкретно вам. Событие OOM-убийства, срабатывание LVE-лимита, факт CPU-throttling — всё это оседает в логах, которые видит только хостинг.
Кое-что иногда доступно и вам напрямую — стоит проверить перед тем, как писать в поддержку:
- на CloudLinux-панелях (большинство cPanel-хостингов) — раздел Resource Usage, где есть счётчик Faults: сколько раз аккаунт реально упёрся в лимит по CPU, памяти или числу процессов за период; подробнее о том, как читать эти цифры и что означают конкретные метрики квоты, — в статье квоты на шаред-хостинге: как измерить, сколько вам реально дали;
- в ISPmanager, DirectAdmin, VestaCP — обычно есть отдельная вкладка «Лимиты» или «Статистика ресурсов» с похожей информацией, формат отличается от провайдера к провайдеру;
- если ничего из этого панель не показывает — остаётся единственный путь: запросить эти данные у поддержки хостинга напрямую, потому что сами логи находятся вне зоны видимости вашего аккаунта в принципе, и это не обходится никакими правами доступа внутри аккаунта.
Прежде чем часами дебажить код: спросите поддержку хостинга напрямую
Самая частая ошибка в этой ситуации — начать чинить то, что не сломано. Разработчик видит обрыв процесса, предполагает баг в своём коде, и следующие несколько часов уходят на добавление логирования, попытки воспроизвести проблему локально, ревью недавних изменений — хотя вопрос решался бы одним письмом в поддержку.
Прежде чем погружаться в долгий дебаг, стоит сначала задать хостингу прямой и конкретный вопрос — конкретность здесь решает, потому что общий вопрос «а у вас там всё нормально?» с высокой вероятностью получит общий ответ «оптимизируйте код». Полезный шаблон обращения:
Аккаунт/домен: example.ru
Время инцидента: 2026-08-27, 14:32-14:35 (UTC+3)
Что наблюдаем: процесс приложения оборвался, в логах приложения
и веб-сервера за этот интервал нет ни одной ошибки — обрыв без
исключения, без стектрейса.
Вопрос: не могли бы вы проверить системные логи по нашему аккаунту
за указанный интервал — было ли принудительное завершение процесса
(OOM killer / LVE лимит / CPU-throttling), и если да — по какой
причине (память, CPU-время, число процессов, число соединений)?
Такой запрос даёт саппорту конкретные координаты для поиска в собственных логах — не «у нас что-то не работает», а точное время и явный вопрос про конкретный механизм. У многих хостингов ответ приходит быстро, потому что смотреть в собственные системные логи для инженера поддержки — секундное дело, в отличие от того, чтобы часами гонять чужой код в поисках несуществующего бага.
Отдельно стоит понимать границу ответственности: поддержка хостинга обязана рассказать, что происходило с ресурсами вашего аккаунта на уровне инфраструктуры, но не обязана и чаще всего не будет чинить логику вашего приложения — это разные зоны ответственности, и путать их не стоит ни вам, ни ей. Если саппорт с порога отвечает шаблонной фразой «оптимизируйте код», не отступайте — переформулируйте вопрос ещё конкретнее, сославшись на отсутствие ошибок в собственных логах именно в указанный интервал, и попросите именно факт (был ли kill) и причину, а не общую рекомендацию.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPSНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Как отличить memory_limit в PHP от внешнего убийства процесса cgroup'ом?
По наличию сообщения. Если интерпретатор сам обнаружил, что упёрся в свой лимит («Allowed memory size exhausted»), он успевает это залогировать — это его собственный контролируемый выход. Если процесс убили снаружи через SIGKILL, никакого сообщения не будет в принципе — оболочка интерпретатора не успевает отработать обработчик, потому что сигнал не перехватывается.
Могу ли я сам, без доступа к dmesg, увидеть, что процесс убили принудительно?
Косвенно — да. Код выхода 137 в терминале или в логе процесс-менеджера — прямое указание на SIGKILL (128 + номер сигнала SIGKILL, который равен 9). Слово «Killed» вместо обычного завершения — туда же. Но точную причину (память, CPU, число процессов) без системных логов хостинга вы не узнаете — увидите только факт, не причину.
Что делать, если поддержка отказывается смотреть системные логи?
Переформулируйте вопрос максимально конкретно: точное время, факт отсутствия ошибок в ваших логах, прямой вопрос про OOM/LVE/CPU-throttling. Если и это не помогает — это само по себе сигнал о качестве поддержки конкретного тарифа, и стоит учитывать это при выборе, оставаться ли на нём.
Это вообще законно — резать процессы без предупреждения?
Да, если это описано (пусть и расплывчато) в Acceptable Use Policy тарифа, с которым вы согласились при регистрации — а описано это почти всегда. Вопрос не в законности, а в том, что формулировки нарочно оставляют мало конкретики, из-за чего лимит и ощущается как «внезапный», хотя формально он предусмотрен условиями с самого начала.
Стоит ли сразу переезжать на VPS, если наткнулись на такое один раз?
Не обязательно. Разовое срабатывание при аномальном всплеске трафика — это нормальная защита инфраструктуры, а не повод для паники. Стоит начать беспокоиться, если это повторяется регулярно и коррелирует с обычным ростом вашей нагрузки, а не с редкими выбросами.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →