← Назад в блог

Как понять, что держит PHP-процесс в BitrixVM: разбор PID без боли

Практический разбор, как найти зависший PHP-процесс в BitrixVM на CentOS: pstree, ps, lsof, strace и htop. Без перезапусков и гаданий.

Как понять, что держит PHP-процесс в BitrixVM: разбор PID без боли

Требования

  • 1C-Битрикс: Виртуальная машина
  • Доступ к серверу
  • Базовое понимание процессов Linux

Как понять, что держит PHP-процесс в BitrixVM

Проблема и контекст

Ситуация типовая для продакшена на 1C-Битрикс:

  • сервер жив, load есть;
  • сайт то отвечает, то нет;
  • cron выполняется странно или вообще «залип»;
  • в htop висит PHP-процесс по 10–30 минут;
  • перезапускать сервисы нельзя или не хочется.

Вопрос звучит просто: что конкретно делает этот процесс и почему он не заканчивается?

Перезапуск PHP-FPM или Apache — крайняя мера. До неё почти всегда можно понять причину.

Обзор PHP-процесса в BitrixVM


Окружение

Разбор актуален для стандартной BitrixVM:

  • CentOS
  • Percona Server 8.0 (MySQL)
  • Apache 2.4.x
  • PHP 8.x
  • Nginx 1.26.x
  • Redis
  • Memcached

Никаких sudo — работаем из-под root, как это обычно и бывает на VM.


Общая логика анализа

Я всегда иду по одному и тому же маршруту:

  1. Найти конкретный PID
  2. Посмотреть дерево процессов
  3. Понять, какие ресурсы он держит
  4. Проверить, на чём он реально завис
  5. Только потом принимать решение

Ниже — по шагам.


Шаг 1. Берём один PID и смотрим дерево

Допустим, в htop увидели подозрительный PHP-процесс.

PID=<один_pid_php>

Дерево процессов

pstree -ap $PID

Что даёт команда:

  • показывает, кто породил процесс;
  • сразу видно, это cron, php, apache или php-fpm;
  • полезно для понимания контекста (агент, CLI, веб).

Часто здесь уже видно что-то вроде:

cron---php---php

И становится понятно, что это не веб-запрос, а фоновая задача.

Детали процесса

ps -o pid,ppid,etime,stat,cmd -p $PID

Разбор полей:

  • etime — сколько времени процесс живёт
  • stat — состояние (R, S, D)
  • cmd — команда запуска (очень важно)

Если etime — десятки минут, а cmd указывает на /bitrix/modules/... — это почти наверняка агент или крон.


Шаг 2. Какие файлы и сокеты он держит

Теперь смотрим, что процесс держит открытым.

Быстрый просмотр файловых дескрипторов

ls -l /proc/$PID/fd | head

Здесь можно увидеть:

  • файлы логов;
  • временные файлы;
  • сокеты.

Если видишь что-то вроде:

socket:[123456]

— идём дальше.

Подробно через lsof

lsof -p $PID | head -n 50

На что смотрим в первую очередь:

  • соединение с MySQL;
  • unix-socket /var/lib/mysql/mysql.sock;
  • файлы в /bitrix/cache, /upload, /tmp.

Важно: если процесс держит MySQL-socket — он уже внутри Битрикса и выполняет бизнес-логику, а не просто висит в PHP.


Шаг 3. На чём он реально «висит» (strace)

Если процесс живёт долго, но CPU почти не ест — он ждёт. Вопрос — чего.

Подключаемся без вмешательства

strace -p $PID -tt -T -f -s 128 -o /tmp/strace.cron_$PID.log

Оставляем на 10–20 секунд, затем Ctrl+C.

Смотрим хвост

tail -n 50 /tmp/strace.cron_$PID.log

Типовые варианты, которые я видел на практике:

  • futex() — ожидание блокировки (часто кеш или shared memory);
  • read() / write() — чтение файла или сокета;
  • poll() / select() — ожидание ответа от MySQL или Redis;
  • open() на файле, который лежит на медленном диске.

Это ключевой момент: ты видишь не догадки, а фактические системные вызовы.

Анализ PHP-процесса через strace


Шаг 4. htop — не просто «посмотреть нагрузку»

htop уже установлен в BitrixVM, и его часто недооценивают.

Что я делаю:

  • включаю отображение Command line;
  • сортирую по TIME+;
  • смотрю, какие процессы живут дольше всех.

Полезные флаги:

  • F5 — дерево процессов;
  • F6 — сортировка;
  • F3 — поиск по имени скрипта.

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


Дополнительные инструменты (по ситуации)

Иногда полезно:

  • vmstat 1 — если подозрение на I/O wait;
  • iostat — если сервер на HDD;
  • netstat -anp | grep $PID — если процесс держит сеть.

Ставить ничего не обязательно, но знать стоит.


Подводные камни

Из практики:

  1. Агент без лимитов Бесконечный цикл + отсутствие таймаутов = вечный PHP.

  2. Большие выборки ORM без limit, особенно в CLI — классика.

  3. Файловый кеш Массовая работа с /bitrix/cache на медленном диске.

  4. MySQL-блокировки Процесс не «завис», он честно ждёт освобождения таблицы.


Безболезненные варианты решения

В порядке увеличения жёсткости:

  1. Понять, что именно делает процесс
  2. Дать ему дожить и исправить код
  3. Ограничить время выполнения (timeout, батчи)
  4. Переписать агент или крон
  5. И только потом — kill

Слепо убивать процесс — почти всегда плохая идея.


Результат

После такого разбора у тебя есть:

  • конкретный скрипт;
  • конкретная точка зависания;
  • понимание, это I/O, MySQL или логика;
  • аргументы для фикса, а не догадки.

Практическая польза

Этот подход:

  • экономит время;
  • не требует перезапусков;
  • применим на любом продакшене;
  • даёт контроль над системой, а не иллюзию.

Если ты работаешь с BitrixVM и PHP — рано или поздно это пригодится.

0 просмотров

Комментарии

Загрузка комментариев...
Пока нет комментариев. Будьте первым!