问题描述
我在一个Ubuntu Server 12.04(64位)VM(VirtualBox)上运行Symfony2。主持人是MacBook专业版。出于某种原因,我在开发模式(app_dev.php)中获得了非常长的请求时间。我知道它在开发模式下速度较慢,但每个请求我说5-7秒(有时甚至更慢)。在我的Mac上,我在开发模式下获得200ms左右的请求时间。
在Symfony2分析器中查看我的时间线后,我注意到~95%的请求时间是”initialization time”。这是什么?有什么原因可能会这么慢?
此问题仅适用于开发模式下的Symfony2,而不适用于我在VM上运行的任何其他站点,甚至不适用于生产模式下的Symfony2。
我看到了这个(http://stackoverflow.com/questions/11162429/whats-included-in-the-initialization-time-in-the-symfony2-web-profiler),但它似乎没有回答我的问题。
最佳解决办法
默认情况下,我有来自Symfony2的5-30秒响应。现在它在开发环境中约为500毫秒。
然后我在php.ini
中修改了以下内容:
-
设置
realpath_cache_size = 4M
(或更多) -
完全禁用
XDebug
(使用phpinfo
测试) -
realpath_cache_ttl = 7200
-
启用并正确设置
OPcache
(或APC) -
重新启动Apache以便重新加载php.ini
而且,在开发模式下,响应不到2秒!希望能帮助到你。
之前:6779毫秒
之后:1587毫秒
Symfony2从数千个文件中读取类,这是一个缓慢的过程。当使用小型PHP实时路径缓存时,如果它们不在PHP的实际路径缓存中,则每次在开发环境中发出新请求时,都需要逐个解析文件路径。 Symfony2默认情况下,实际路径缓存太小。在产品中,这当然不是问题。
缓存元数据:
缓存元数据(例如映射)对于进一步提升性能也非常重要:
doctrine:
orm:
entity_managers:
default:
metadata_cache_driver: apc
query_cache_driver: apc
result_cache_driver: apc
您需要为此启用APCu
。没有字节码缓存的是APC
,因为OPCache
已经进行了操作码缓存。 OPCache
自PHP 5.5开始内置。
—-之后:467 ms —-
(在prod环境中相同的响应是~80 ms)
请注意,这个项目使用30多个捆绑包,并且拥有数万行代码,几乎有100个自己的服务,所以0.5s在本地Windows环境中使用一些简单的优化就相当不错。
次佳解决办法
我找出了问题的原因(而不是Symfony2)。由于某些原因,在ubuntu VM上,某些文件的修改时间不正确(即将来等)。当symfony2使用 filemtime()对其注册表检查这些时间时,它确定缓存不再是新鲜的并且它重建整个事物。我还没弄清楚为什么会这样做。
第三种解决办法
我还需要禁用xdebug (v2.2.21)
来调试我的macbook上的apache2 max timeout loading。它是使用macports安装的:
sudo port install php54-xdebug.
启用xdebug后,每个页面都会耗尽最大加载时间,并且会发送致命错误,超出调度的最大超时消息。禁用时,一切都在合理的预期时间内正常加载。我使用MAMP来实现这一点,默认情况下没有启用xdebug,并且apache2像往常一样快速运行。我可能会换另一个调试器,这很糟糕,因为xdebug以前工作正常。
配置:
-
MacOSX 10.6.8
-
macports 2.1.3
-
Apache 2.2.24
-
PHP 5.4
第四种办法
我们有同样的问题。在这里,每个请求我们有10秒或更多。我看看我是否删除了bootstrap.php.cache中的以下行,所有时间都返回正常状态(298 ms)。
foreach ($meta as $resource) {
if (!$resource->isFresh($time)) {
return false;
}
}
我们可能有错误的修改时间,但我们不知道如何修复。有人知道解决方案吗?
第五种办法
正如在https://stackoverflow.com/a/12967229/6108843中所说,这种行为的原因可能是Ubuntu VM设置。您应该按照https://superuser.com/questions/463106/virtualbox-how-to-sync-host-and-guest-time中的说明在主机和客户操作系统之间同步日期和时间。
通过FTP将文件上载到VM时,文件修改日期将更改为主机的值。这就是为什么 filemtime()返回错误的值。
第六种办法
您可以移动APP/var/cache
в/dev/shm/YourAppName/var/cache
。但是,对于IDE自动完成和代码验证,在本地文件中构建容器也是很好的。在app/AppKernel.php
中:
public function getCacheDir()
{
return $this->getVarOrShmDir('cache/' . $this->getEnvironment());
}
public function getLogDir()
{
return $this->getVarOrShmDir('logs');
}
private function getVarOrShmDir($dir)
{
$result = dirname(__DIR__) . '/var/' . $dir;
if (
in_array($this->environment, ['dev', 'test'], true) &&
empty($_GET['warmup']) && // to force using real directory add ?warmup=1 to URL
is_dir($result) && // first time create real directory, later use shm
file_exists('/bin/mount') && shell_exec('mount | grep vboxsf') // only for VirtualBox
) {
$result = '/dev/shm/' . 'YourAppName' . '/' . $dir . '/' . $this->getEnvironment();
}
return $result;
}