
В настоящее время я настраиваю общую среду тестирования для одного из наших приложений, написанного на PHP5.3 и использующего фреймворк Symfony2.
Если я размещаю только один экземпляр приложения на сервере, все работает так, как и должно.
Однако если я затем разверну дополнительные экземпляры приложения (которые могут использовать или не использовать тот же самый код, в зависимости от настроек клиента), я получу такие ошибки:
[Tue Nov 06 10:19:23 2012] [error] [client 127.0.0.1] PHP Warning: require(/var/www/vhosts/application1/httpdocs/vendor/doctrine-common/lib/Doctrine/Common/Annotations/AnnotationRegistry.php): failed to open stream: Operation not permitted in /var/www/vhosts/application2/httpdocs/app/bootstrap.php.cache on line 1193
[Tue Nov 06 10:19:23 2012] [error] [client 127.0.0.1] PHP Fatal error: require(): Failed opening required '/var/www/vhosts/application1/httpdocs/app/../vendor/doctrine-common/lib/Doctrine/Common/Annotations/AnnotationRegistry.php' (include_path='.:/usr/share/pear:/usr/share/php') in /var/www/vhosts/application2/httpdocs/app/bootstrap.php.cache on line 1193
По сути, второй сайт пытается потребовать файлы с первого сайта, но из-за ограничений open_basedir он не может этого сделать. Я не хочу отключать open_basedir, так как это только маскирует проблему, а не решает ее, и создает зависимость между приложениями, которой не должно быть.
Сначала я думал, что это связано с ошибкой Symfony2, но теперь я выяснил, что это проблема с APC; отключение APC также устраняет ошибку, но меня беспокоит влияние этого на производительность.
Есть ли у кого-нибудь предложения, что я могу сделать?
решение1
Хорошо, оказалось, что проблема была в нашем собственном коде, а не в чем-то конкретном, связанном с APC или Symfony2.
Для справки тем, кто может столкнуться с этим:
Мы использовали компонент ApcUniversalClassLoader из Symfony2.
Это позволяет вам указать префикс для ваших кэш-файлов.
Этот префикс был одинаковым для каждого экземпляра нашего приложения; поэтому он работал нормально, пока на каждом сервере был только один экземпляр.
Поскольку префикс был тем же, APC попытался загрузить классы, принадлежащие первому экземпляру приложения, к которому был осуществлен доступ сразу после перезапуска сервера.
Изменение префикса на разный для каждого экземпляра приложения позволяет добиться корректной работы приложения, загружая классы из правильных папок.
Надеюсь, это убережет кого-то от удара головой об стол, когда он поймет, почему это не работает :)