使用预加载时可以运行多个Symfony应用程序吗?

问题描述

我在不同的子域上有2个单独的Symfony安装。
但是,当我尝试访问第二个域时,它说:

致命错误:无法在/ var /中重新声明Symfony \ Component \ String \ u()(先前在/var/www/public_api/releases/20200904200316/vendor/symfony/string/Resources/functions.PHP:14中声明) www / public_test_api / releases / 20200909003532 / vendor / symfony / string / Resources / functions.PHP,第14行

请注意,冲突发生在不同目录之间,彼此之间没有任何关系。

这是缓存问题吗?我该如何解决?我尝试为第二次安装禁用OPCache,但是它没有任何改变。 APCu也已启用。

我也遇到了同样使用Symfony的第三方软件的相同问题。

禁用opcache.preload设置似乎可以解决此问题。

是否可以在同一服务器上运行所有这些应用程序并从预加载中受益?

解决方法

对于在同一服务器中多次使用的类,不能使用预加载。

通过读取opcache.preload中指定的文件,预加载将相关的定义保留在内存中。如果您预先加载一个Symfony实例,然后尝试加载另一个Symfony实例,则会遇到定义冲突(因为这是发生在您身上的)。

实际上,要想从预加载中受益,就需要具有隔离的“专用”服务器,即使这些服务器不是物理机而是虚拟机或容器。

original RFC for this feature中所述:

[...]这种方法与托管多个应用程序或应用程序的多个版本的服务器不兼容-如果从某个类的代码库中预先加载了此类,则它们对于具有相同名称的某些类将具有不同的实现应用程序,它将与从其他应用程序加载不同的类实现冲突。


TLDR;您不能在同一服务器上的预加载中使用相同类的多个实例。您必须关闭预加载功能,或者将每个应用程序移到它们自己的专用容器中,在这些容器中它们不会共享PHP-FPM进程。