【问题标题】:Why is my Symfony 2.0 site running slowly on Vagrant with Linux host?为什么我的 Symfony 2.0 站点在带有 Linux 主机的 Vagrant 上运行缓慢?
【发布时间】:2018-09-13 16:04:54
【问题描述】:

我有一个 Symfony 2.0 应用程序,它使用 Vagrant 与 Linux 来宾和主机操作系统 (Ubuntu) 一起运行。但是,它运行缓慢(例如,加载页面需要几秒钟,通常超过 10 秒),我不知道为什么。我在本地而不是在 Vagrant VM 上运行该站点的同事运行得更快。

我在其他地方读到过,如果未启用 NFS,Vagrant VM 的运行速度会非常慢,但我已经启用了它。我也在使用 APC 缓存来尝试加快速度,但问题仍然存在。

我使用http://webmozarts.com/2009/05/01/speedup-performance-profiling-for-your-symfony-app 的说明对我的网站运行了 xdebug,但我不清楚从哪里开始分析数据。我已经在 KCacheGrind 中打开它并在“Incl”下寻找高数字。和“自我”,但这只是表明php::session_start 需要很长时间。

关于我应该在这里尝试什么的任何建议?抱歉,这个问题有点笼统,但我很难过!

【问题讨论】:

  • 这看起来真是个好主意!我不再使用 Vagrant,但我已经让工作人员知道了。他们中的一些人在使用 Vagrant,但我不确定他们是否还在使用。
  • 也高度相关:erikaheidi.com/2013/09/24/…
  • Vagrant 1.5 中的一个新东西是rsync support,它显然提供了“以一点延迟为代价的令人难以置信的 I/O 性能”。我还没有尝试过,但看起来它在这里可能会有所帮助。

标签: symfony vagrant


【解决方案1】:

我在我的 OS X 主机上看到了类似的问题,我忘记启用 NFS! 在 Windows 主机上,性能影响不太真实...... 对于我非常小的网站,我有 12649 个文件...所以很容易达到 1000+ 个文件的限制。

所以我的两分钱:在你的 Vagrantfile 中像这样启用 NFS

config.vm.share_folder "v-root", "/vagrant", ".." , :nfs => true

来自专家:

随着共享文件夹中文件数量的增加,VirtualBox 共享文件夹的性能会迅速下降,这是一个众所周知的问题。当一个项目达到 1000 多个文件时,执行简单的操作(例如运行单元测试甚至只是运行应用服务器)可能比在本机文件系统上慢许多数量级(例如,从 5 秒到超过 5 分钟)。

如果您在共享文件夹中看到这种性能下降,NFS 共享文件夹可以提供解决方案。 Vagrant 将在主机上编排 NFS 服务器的配置,并为您将文件夹挂载到客户机上。

注意:Windows 主机不支持 NFS。根据 VirtualBox 的说法,Windows 上的共享文件夹不应遭受与基于 Unix 的系统相同的性能损失。如果这不是真的,请随时使用我们的支持渠道,也许我们可以为您提供帮助。

编辑:

在 Windows 上,我找到了另一个解决方案,我在我的项目中的供应商文件夹上使用符号链接 (ln -fs) 链接到非共享文件夹。这减少了 Windows 主机、防病毒软件等看到的文件数量。

【讨论】:

  • 我在我的 Vagrantfile 中使用以下行,因为这意味着它为非 Windows(它可以工作)而不是 Windows(它不能)加载它:config.vm.share_folder("v-root", "/vagrant", "./", :nfs => !RUBY_PLATFORM.downcase.include?("w32"))
  • 您是否尝试不共享 vagrant 中的文件夹并运行 rsync 作业将文件推送到 vagrant 框?这有点棘手,但如果您的响应时间提高了很多作为回报.. 可能是值得的
  • "'v-root' 共享文件夹已重命名为 'vagrant-root'" - 如果使用新版本的 Vagrant,请记住这一点。
  • 注意:使用 Vagrant 1.1 语法,该行应该是:config.vm.synced_folder ".", "/vagrant", :nfs => !RUBY_PLATFORM.downcase.include?("w32")
  • windows 的绝佳解决方案是 vagrant 插件:vagrant-winnfsd - 为 windows 启用 NFS。
【解决方案2】:

在我工作的地方,我们尝试了两种解决方案来解决 Vagrant + Symfony 运行缓慢的问题。我推荐第二个(nfs 和绑定挂载)。

rsync 方法

首先,我们使用rsync。我们的方法与AdrienBrault's answer 中概述的方法略有不同。相反,我们在Vagrantfile 中有如下代码:

config.vm.define :myproj01 do |myproj|
  # Networking & Port Forwarding
  myproj.vm.network :private_network, type: "dhcp"
  # NFS Share
  myproj.vm.synced_folder ".", "/home/vagrant/current", type: 'rsync', rsync__exclude: [
    "/.git/",
    "/vendor/",
    "/app/cache/",
    "/app/logs/",
    "/app/uploads/",
    "/app/downloads/",
    "/app/bootstrap.php.cache",
    "/app/var",
    "/app/config/parameters.yml",
    "/composer.phar",
    "/web/bundles",
    "/web/uploads",
    "/bin/behat",
    "/bin/doctrine*",
    "/bin/phpunit",
    "/bin/webunit",
  ]
  # update VM sooner after files changed
  # see https://github.com/smerrill/vagrant-gatling-rsync#working-with-this-plugin
  config.gatling.latency = 0.5
end

您可能从上面注意到,我们使用Vagrant gatling rsync plugin 保持文件同步。

改进的 NFS 方法,使用绑定挂载(推荐解决方案)

rsync 方法解决了速度问题,但我们发现它存在一些问题。特别是,当在 VM 上生成文件(如 composer.lock 或 Doctrine 迁移)时,或者当我们想要访问 /vendor 中的代码时,它的单向特性(与共享文件夹相反)很烦人。我们必须通过 SFTP 将内容复制回来 - 对于新文件,请在下一次运行 gatling 插件清除它们之前执行此操作!

因此,我们转向使用binding mounts 以不同方式处理缓存和日志等文件夹的解决方案。不共享这些会大大提高速度。

Vagrantfile的相关位如下:

# Binding mounts for folders with dynamic data in them
# This must happen before provisioning, and on every subsequent reboot, hence run: "always"
config.vm.provision "shell",
  inline: "/home/vagrant/current/bin/bind-mounts",
  run: "always"

上面引用的bind-mounts 脚本如下所示:

#!/bin/bash

mkdir -p ~vagrant/current/app/downloads/
mkdir -p ~vagrant/current/app/uploads/
mkdir -p ~vagrant/current/app/var/
mkdir -p ~vagrant/current/app/cache/
mkdir -p ~vagrant/current/app/logs/

mkdir -p ~vagrant/shared/app/downloads/
mkdir -p ~vagrant/shared/app/uploads/
mkdir -p ~vagrant/shared/app/var/
mkdir -p ~vagrant/shared/app/cache/
mkdir -p ~vagrant/shared/app/logs/

sudo mount -o bind ~vagrant/shared/app/downloads/ ~/current/app/downloads/
sudo mount -o bind ~vagrant/shared/app/uploads/ ~/current/app/uploads/
sudo mount -o bind ~vagrant/shared/app/var/ ~/current/app/var/
sudo mount -o bind ~vagrant/shared/app/cache/ ~/current/app/cache/
sudo mount -o bind ~vagrant/shared/app/logs/ ~/current/app/logs/

NFS + 绑定挂载是我推荐的方法。

【讨论】:

  • 澄清一下:我们也使用了更新版本的 Symfony2,而不仅仅是我原来的问题 (2.0) 中提到的版本。
  • 使用 Symfony 的新布局,您只需要绑定挂载 var - 任何改变的东西都在那里。见stackoverflow.com/a/23994473/3408
【解决方案3】:

ATM,基本上,不要将您的网站代码放在 /vagrant 共享文件夹中。 由于它在您的 VM 和主机 O/S 之间共享,因此速度较慢;而且我没有找到任何有效的解决方案来获得良好的性能。 我们使用的解决方案是从经典的 /var/www 为我们的开发应用程序提供服务,并使用 rsync 使它们与我们的本地副本保持同步。

【讨论】:

  • 所以你还在使用 vagrant 的虚拟机创建功能,而不是共享文件夹位?我是否正确,您使用 rsync 将主机上的代码与来宾上的 /var/www 同步?只是想确保我已经理解你的建议!谢谢
  • 好的,谢谢。我会等着看是否有人有任何建议可以让我继续以标准方式使用 Vagrant,但如果没有,我可以调查你提到的选项。感谢您的帮助。
  • 最后我选择从本地机器而不是虚拟机运行,因为这与团队其他成员在这个项目上所做的相匹配,我可以重用本地机器为需要它的其他项目设置。不过感谢您的意见,我以后可能还会尝试这个。
  • @AdrienBrault 你能自动保持工作副本和/var/www 同步,还是你必须手动执行该步骤?
  • @shanethehat 我使用 PHPStorm,你可以配置一个远程服务器,phpstorm 在文件保存时自动上传到它
【解决方案4】:

按照本文中的说明Speedup Symfony2 on Vagrant boxes 帮助我解决了这个问题,将我的 Symfony2 项目的页面加载时间从 6-10 秒减少到 1 秒。基本上所有的解决方法是使用 NFS 设置主机和来宾(vagrant VM 框)之间的同步类型,而不是使用非常慢的 VirtualBox 共享文件夹系统。

还将以下代码添加到 Symfony2 项目的 AppKernel.php 中,将缓存和日志目录更改为 vagrant 盒上的共享内存目录(/dev/shm),而不是将它们写入 NFS 共享,因此它改进了页面加载速度更快。

<?php

class AppKernel extends Kernel
{
    // ...

    public function getCacheDir()
    {
        if (in_array($this->getEnvironment(), array('dev', 'test'))) {
            return '/dev/shm/appname/cache/' .  $this->getEnvironment();
        }

        return parent::getCacheDir();
    }

    public function getLogDir()
    {
        if (in_array($this->getEnvironment(), array('dev', 'test'))) {
            return '/dev/shm/appname/logs';
        }

        return parent::getLogDir();
    }
}

【讨论】:

    【解决方案5】:

    我使用 sshfs 在主机操作系统和虚拟机之间共享目录(Windows 的扩展驱动器) 比原生 VBox 目录共享快很多

    【讨论】:

    • 你用过 Vagrant 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-05
    • 2016-03-27
    • 1970-01-01
    • 2019-12-16
    • 1970-01-01
    • 2017-11-10
    • 2019-03-22
    相关资源
    最近更新 更多