Началось всё с сообщения о проблеме с отправкой почты: некоторым клиентам Битрикс отправлял письма с пустыми телами, просто терялось тело письма в случайные моменты времени, это не зависело от частоты отправки, загрузки сервера и т.п. Решено было перехватывать пустые тела и отменять отправку таких писем, на следующем хите такие письма отправлялись уже с телом – такой вот костыль.

Следующий случай был уже серьезнее. И на первый взгляд не имел ничего общего с первой проблемой. Было замечено, что при выгрузке товаров из 1С часть товаров не обновлялись. В результате очень долгого анализа и изучения механики обмена было установлено, что, начиная со случайного товара в выгрузке, XML-файл неверно считывался в базу – неверно строилось дерево. Получалось, что передан полностью валидный файл, но обрабатываются при выгрузке не все товары.

Были намёки на неверный параметр mbstring.func_overload, который Битрикс настойчиво просит установить в "2". Но phpinfo показывал, что это так и было настроено. Но, в очередной раз перебирая все возможные версии, я опять зашел проверить func_overload в phpinfo и увидел "0". Обновляя страницу, я видел и "2", и "0"(реже), т.е. mbstring.func_overload менялся абсолютно случайно.


Причиной этого оказалось то, что для одного из location в nginx мне нужно было установить особые параметры fastcgi, т.к. там использовался PHPExcel и я воспользовался решением, найденным в интернете:

location /special/path/ {
    ...
    fastcgi_param PHP_VALUE "mbstring.func_overload=0";
    ...
}

Все location в этом конфиге передавали запросы на один пул php-fpm и выглядело так, что этот параметр PHP_VALUE применяется к процессу и все дальнейшие запросы, переданные этому процессу, выполняются с этим параметром. Получается, что если процесс fpm создаётся на запрос к этому особому пути, то все дальнейшие запросы будут выполнены с mbstring.func_overload=0 и вызовут ошибку. В интернете можно найти подобные случаи и даже багрепорты на сайте php, но неизвестно, является ли это нормальным поведением, багом или особенностью php-fpm.

Для этой проблемы есть 2 пути решения: создавать отдельные пулы или прописать всем location соответствующий fastcgi_param. Надеюсь эта статья поможет кому-то и он отпишется о проверке второго пути решения в комментариях.