我目前正在为我们的一个应用程序设置一个共享的登台环境,该应用程序用 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 的任何特定错误。
供其他可能遇到此问题的人参考:
我们正在使用 Symfony2 的 ApcUniversalClassLoader 组件。
这允许您为缓存文件指定前缀。
这个前缀在我们应用程序的每个实例中都是相同的;这就是为什么只要每个服务器只有一个实例它就能正常工作。
由于前缀相同,APC 尝试加载在服务器重新启动后立即访问的应用程序第一个实例的类。
将前缀更改为应用程序的每个实例都不同,可以使其正确运行,并从正确的文件夹加载类。
希望这可以防止其他人在意识到为什么它不起作用时撞到桌子上:)