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 дней гарантии