Yandex Metrika
sanches.free 1 просмотр

Nginx и PHP‑FPM: почему «прыгает» mbstring.func_overload на Битрикс

Когда «разные» баги оказываются одним механизмом

Сначала жаловались на почту: часть писем из «1С-Битрикс» уходила получателям с пустым телом — непредсказуемо, без явной связи с нагрузкой. Временную подстраховку можно собрать на уровне приложения (не отправлять пустое и повторить на следующем хите), но сама история уже намекает на нестабильное окружение PHP.

Позже всплыла другая симптоматика: при выгрузке номенклатуры из 1С часть строк каталога не обновлялась. После долгого разбора пайплайна обмена выяснилось, что где‑то после произвольного элемента в пакете XML парсился «не тем» образом дерево офферов — файл при этом мог быть формально корректным, а обрабатывался не весь массив.

Подозрение на mbstring.func_overload

Для штатной работы Битрикс рекомендует значение mbstring.func_overload = 2. На первый осмотр в phpinfo() оно действительно отображалось как «два». Но при многократном обновлении страницы иногда проступало 0; переключение между значениями выглядело случайным и не воспроизводилось «по времени», а именно между разными запросами.

Виноватый фрагмент nginx

В конфигурации уже стояло отдельное location под устаревшую генерацию таблиц (аналог задач вроде старых XLS-библиотек), где в интернете часто советуют обнулить перегрузку mbstring. Пример паттерна:

location /reports/legacy/ {
    # ...общие параметры upstream...
    fastcgi_param PHP_VALUE "mbstring.func_overload=0";
}

Все виртуальные пути пробрасывались на один и тот же пул php-fpm. Практически получалось так: процесс-посредник мог создаваться первым именно этим особым префиксом и «залипать» с переданным в сессию PHP_VALUE. Следующие обычные хиты уже шли тем же рабочим процессом и наследовали mbstring.func_overload=0, пока пул как‑то пересоздавался или не попадался другой воркер — отсюда и мигающие значения в phpinfo, и «плавающие» сценарии с почтой и XML.

В открытых обсуждениях php и php-fpm встречаются похожие отчёты: поведение спорное (баг против ожиданий), но для эксплуатации важнее стабильный предсказуемый итог, а не классификация в документации.

Два рабочих направления исправления

  • Разнести пулы: вынести «особый» каталог хотя бы в отдельный pool.d/*.conf с собственным сокетом и отдельной группой воркеров, чтобы параметры вида PHP_VALUE не протекали в основной интернет‑магазин и административную панель.
  • Согласовать директивы для всех location: если пул общий по архитектурным причинам, явно пропишите одинаковый нужный профиль mbstring через fastcgi_param PHP_VALUE ... (или управляемую альтернативу через php_admin_value в конфигурации самого воркера) так, чтобы ни один блок не задавал противоречащее остальной среде значение «молча».

Практический вывод

На связке nginx + php-fpm маленький «особый» location с точечными настройками PHP способен ломать кодировочные предположения ядра Битрикс и обменные сценарии. После перевода узкого функционала на изолированный пул или унификации параметров дисперсия исчезает: и почтовые тексты приходят стабильно, и дерево торговых предложений после обновления файла собирается целиком.

Не хотите копаться сами?

Починю за 1-3 дня. Без предоплаты — оплата по результату.

15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии