
現在、PHP5.3 で記述され、Symfony2 フレームワークを使用しているアプリケーションの 1 つに共有ステージング環境を設定しています。
サーバーごとにアプリケーションのインスタンスを 1 つだけホストすると、すべてが正常に動作します。
ただし、その後アプリケーションの追加インスタンスを展開すると (クライアントのカスタマイズに応じて、まったく同じコードを共有する場合とそうでない場合があります)、次のようなエラーが発生します。
[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
基本的に、2 番目のサイトは最初のサイトからのファイルを要求しようとしていますが、open_basedir の制限によりそれができません。open_basedir を無効にすると、問題が解決されるのではなく、問題が隠されるだけであり、存在すべきではないアプリケーション間の依存関係が作成されるため、無効にするつもりはありません。
当初、これは Symfony2 のエラーに関連していると考えていましたが、現在は APC の問題であることが判明しました。APC を無効にするとエラーも解決しますが、これを行うとパフォーマンスにどのような影響が出るか心配です。
私が何ができるかについて、何か提案はありますか?
答え1
わかりました。これは、APC または Symfony2 に特に問題があるのではなく、私たち自身のコードに問題があることが判明しました。
これに遭遇する可能性のある他の人への参考として:
Symfony2 の ApcUniversalClassLoader コンポーネントを使用していました。
これにより、キャッシュ ファイルのプレフィックスを指定できます。
このプレフィックスはアプリケーションの各インスタンスで同じでした。そのため、サーバーごとにインスタンスが 1 つしかない限りは正常に動作しました。
プレフィックスが同じであったため、APC は、サーバーの再起動直後にアクセスされたアプリケーションの最初のインスタンスに属するクラスをロードしようとしました。
アプリケーションのインスタンスごとにプレフィックスが異なるように変更すると、正しいフォルダーからクラスが読み込まれ、正しく動作するようになります。
うまくいけば、これが機能しない理由に気付いたときに、他の誰かが机に頭をぶつけるのを防ぐことができるでしょう :)