gpt4 book ai didi

PHP factor 30 从 Linux 到 Windows 的性能差异

转载 作者:行者123 更新时间:2023-12-01 17:39:51 27 4
gpt4 key购买 nike

我们的团队正在开发 WordPress 插件并在几个独立服务器上提供托管实例。我们的 WordPress 安装由 Git 管理,所有服务器都部署了相同的源和 WordPress 设置,只有域和数据库中的实际数据有所不同。对于每次安装,MySql 都在同一台主机上运行。 WordPress 专门在每台服务器上运行。
然而,在 Windows Server 2008 RC2 上部署此设置后,我们注意到与其他服务器相比有显着的性能差异:页面生成时间从 avg.使用 PHP 生成的页面为 400 毫秒到 4000-5000 毫秒。对于仅由 Apache 提供的静态资源,速度与在 linux 上大致相同。
所以我们采取了一些措施来缩小问题的范围:

  • 确保没有防病毒软件运行或其他 Windows 域干扰
  • 收集分析数据以识别脚本执行期间的时间杀手
  • 测试不同的服务器和硬件设置
  • 仔细检查 Apache 和 PHP 配置是否存在明显的配置错误

  • 经过一些分析后,我们很快注意到,在我们的 Windows 机器上,正则表达式的计算速度非常慢。评估 10.000 个正则表达式 ( preg_match ) 在 Linux 上需要大约 90 毫秒,在 Windows 上需要 3000 毫秒。
    下面提供了分析、系统测试和配置详细信息。 我们不想优化这个脚本(我们知道怎么做)。我们希望脚本在 Windows 上的运行速度与在 Linux 上的运行速度大致相同(假设有关 opcache/... 的设置相同)。也无需优化脚本的内存占用。
    更新:一段时间后,系统似乎内存不足,触发内存不足异常和随机分配。有关更多详细信息,请参见下文。重新启动 Apache/PHP 暂时解决了这个问题。 _get_browser 的跟踪是:
    File (called from)
    require wp-blog-header.php (index.php:17)
    wp (wp-blog-header.php:14)
    WP->main (functions.php:808)
    php::do_action_ref_array (class-wp.php:616)
    php::call_user_func_array (wp-includes/plugin:507)
    wp_slimstat::slimtrack (php::internal (507))
    wp_slimstat::_get_browser (wp-slimstat.php:385)
    更新 2 :由于某种原因,我不记得我们回到在服务器上将 PHP 作为 Apache 模块激活(同样会导致性能不佳)。但是今天它们运行得非常快(约 1 秒/请求)。添加 Opcache 将其降低到约 400 毫秒/请求。 Apache/PHP/Windows 保持不变。
    1) 分析结果
    分析是在所有机器上使用 XDebug 完成的。通常我们只收集了几次运行——这些足以揭示大部分时间(50%+)花费的位置:WordPress 插件 [get_browser][1]wp-slimstats 方法:
    protected static function _get_browser(){
    // Load cache
    @include_once(plugin_dir_path( __FILE__ ).'databases/browscap.php');
    // browscap.php contains $slimstat_patterns and $slimstat_browsers

    $browser = array('browser' => 'Default Browser', 'version' => '1', 'platform' => 'unknown', 'css_version' => 1, 'type' => 1);
    if (empty($slimstat_patterns) || !is_array($slimstat_patterns)) return $browser;

    $user_agent = isset($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:'';
    $search = array();
    foreach ($slimstat_patterns as $key => $pattern){
    if (preg_match($pattern . 'i', $user_agent)){
    $search = $value = $search + $slimstat_browsers[$key];
    while (array_key_exists(3, $value) && $value[3]) {
    $value = $slimstat_browsers[$value[3]];
    $search += $value;
    }
    break;
    }
    }

    // Lots of other lines to relevant to the profiling results
    }
    这个函数类似于 PHP 的 get_browser 检测浏览器的功能和操作系统。大部分脚本执行时间都花在这个 foreach 循环中,评估所有这些 preg_match(每个页面请求大约 8000 - 10000)。这在 Linux 上大约需要 90 毫秒,在 Windows 上大约需要 3000 毫秒。所有测试设置的结果都相同(图片显示了两次执行的数据):
    wp_slimstat::_get_browser profiling results on IIS8
    当然,加载两个巨大的数组需要一些时间。也评估正则表达式。但我们预计它们在 Linux 和 Windows 上花费的时间大致相同。这是在 linux vm 上的分析结果(仅限一页请求)。区别非常明显:
    enter image description here
    另一个时间杀手实际上是 WordPress 使用的对象缓存:
    function get( $key, $group = 'default', $force = false, &$found = null ) {
    if ( empty( $group ) )
    $group = 'default';

    if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
    $key = $this->blog_prefix . $key;

    if ( $this->_exists( $key, $group ) ) {
    $found = true;
    $this->cache_hits += 1;
    if ( is_object($this->cache[$group][$key]) )
    return clone $this->cache[$group][$key];
    else
    return $this->cache[$group][$key];
    }

    $found = false;
    $this->cache_misses += 1;
    return false;
    }
    时间花在这个函数本身上(3 个脚本执行):
    enter image description here
    在 Linux 上:
    enter image description here
    最后一个真正的大杀器是翻译。在 WordPress 中,从内存中加载的每个翻译需要 0.2 毫秒到 4 毫秒的时间:
    enter image description here
    在 Linux 上:
    enter image description here
    2) 测试系统
    为了确保虚拟化或 Apache 确实会影响这一点,我们在多个设置上对此进行了测试。 Antivir 在所有设置中都被禁用:
  • Linux Debian、Apache 2 和 PHP 的最新稳定版本。这对于在虚拟机中运行的开发人员和在临时/实时服务器中运行是一样的。作为所需性能的引用系统。要么在我们的办公室运行,要么在某些托管服务提供(共享空间)。 Windows 系统的内存在 4GB 到 8GB 之间,内存使用率一直低于 50%。虚拟化永远不会同时运行 Windows 和 Apache。
  • Life-Servers,在 T-Systems(托管虚拟化服务器)上运行,在 VMWare Player 上
  • 赢得 2008 R2。 Apache 2.2.25 + PHP 5.4.26 NTS,VC9 作为 fastcgi 模块
  • 赢得 2008 R2。 Apache 2.2.25 + PHP 5.5.1 NTS,VC11 作为 fastcgi 模块
  • 赢得 2008 R2。 Apache 2.2.25 + PHP 5.5.1 NTS,VC11 作为 Apache 模块
  • Win 2008 R2、Apache 2.2.25 + PHP 5.5.11 TS、VC11 作为 apache 模块(这是我在更新 2 中提到的快速模块)

  • 在本地机器上,主机:OpenSuse,虚拟化:VMWare 播放器,与@T-Systems 相同。为了避免他们的基础设施影响我们:
  • 赢得 2008 R2。 Apache 2.2.25 + PHP 5.4.26 NTS,VC9 作为 fastcgi 模块
  • 赢得 2008 R2。 IIS7 + PHP 5.4.26 NTS,VC9 作为 fastcgi 模块(有和没有 wincache)
  • Win 2012。IIS * + PHP 5.5.10 NTS,VC11 作为 fastcgi 模块(有和没有 wincache)

  • 在没有虚拟化的本地机器上
  • 赢得 2008 R2。 Apache 2.2.25 + PHP 5.4.26 NTS,VC9 作为 fastcgi 模块


  • 上面提到的分析结果在不同的系统上是相同的(约 10% 的推导)。 Windows 总是比 Linux 慢的一个重要因素。
    使用全新安装的 WordPress 和 Slimstats 导致大约。相同的结果。在这里重写代码不是一种选择。
    更新 :同时,我们发现了另外两个 Windows 系统(Windows 2008 R2、VM 和 Phys),其中这个完整的堆栈运行速度非常快。不过配置一样。
    更新 2 :在 Life-Servers 上将 PHP 作为 apache 模块运行的速度比 fastcgi 方法稍快:下降到约 2 秒,减少 50%。
    内存不足
    一段时间后,我们的 Live-Server 完全停止工作,触发这些内存不足异常:
    PHP Fatal error:  Out of memory (allocated 4456448) (tried to allocate 136 bytes)
    PHP Fatal error: Out of memory (allocated 8650752) (tried to allocate 45 bytes)
    PHP Fatal error: Out of memory (allocated 6815744) (tried to allocate 24 bytes)
    这发生在随机脚本位置。显然 Zend 内存管理器无法分配更多内存,尽管脚本可以这样做。当时,如果发生事故,服务器有大约 50% 的可用 RAM (2GB+)。所以服务器实际上并没有用完 ram。重新启动 Apache/PHP 暂时解决了这个问题。
    不确定此问题是否与此处的性能问题有关。然而,由于这两个问题似乎都与内存有关,因此将其包含在此处。特别是我们将尝试重现提供良好性能的 Windows 测试的设置。
    3) Apache 和 PHP 配置
    ...可能没有任何常见的陷阱。输出缓冲已启用(默认),多字节覆盖禁用,......如果有任何选项感兴趣,我们很乐意提供它们。 httpd.exe -V 的输出
    Server version: Apache/2.4.7 (Win32)
    Apache Lounge VC10 Server built: Nov 26 2013 15:46:56
    Server's Module Magic Number: 20120211:27
    Server loaded: APR 1.5.0, APR-UTIL 1.5.3
    Compiled using: APR 1.5.0, APR-UTIL 1.5.3
    Architecture: 32-bit
    Server MPM: WinNT
    threaded: yes (fixed thread count)
    forked: no
    Server compiled with....
    -D APR_HAS_SENDFILE
    -D APR_HAS_MMAP
    -D APR_HAVE_IPV6 (IPv4-mapped addresses disabled)
    -D APR_HAS_OTHER_CHILD
    -D AP_HAVE_RELIABLE_PIPED_LOGS
    -D DYNAMIC_MODULE_LIMIT=256
    -D HTTPD_ROOT="/apache"
    -D SUEXEC_BIN="/apache/bin/suexec"
    -D DEFAULT_PIDLOG="logs/httpd.pid"
    -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
    -D DEFAULT_ERRORLOG="logs/error.log"
    -D AP_TYPES_CONFIG_FILE="conf/mime.types"
    -D SERVER_CONFIG_FILE="conf/httpd.conf"
    mpm_winnt_module 配置:
    <IfModule mpm_winnt_module>
    ThreadsPerChild 150
    ThreadStackSize 8388608
    MaxConnectionsPerChild 0
    </IfModule>
    php.ini 的摘录:
    realpath_cache_size = 12M
    pcre.recursion_limit = 100000
    4) 当前疑似原因
    旧假设:

    All three examples heavily rely on big arrays and string operations. That some kind seems to be the common factory. As the implementation works ok'ish on Linux, we suspect this to be a memory problem on Windows. Given there is no database interaction at the pin-pointed locations, we don't suspect the database or Server <-> PHP integration to be the problem. Somehow PHP's memory interaction just seems to be slow. Maybe there is someone interfering with the memory on Windows making access dramatically slower?


    旧假设 2:

    As the same stack runs fine on other Windows machines we assume the problem to be somewhere in the Windows configuration.


    新假设 3:

    Actually I am out of assumptions. Why would run PHP that much slower as fastcgi then as apache module>


    关于如何验证这一点或在这里找到真正问题的任何想法?非常欢迎解决此问题的任何帮助或指导。

    最佳答案

    Windows 有许多服务/策略,可以在各种情况下限制、阻止、保护、控制计算机的使用等。

    一位优秀的 Microsoft 认证专家将能够在几分钟内解决您的问题,因为他们将拥有准确判断哪些设置/服务/策略要检查和禁用/启用/更改设置的经验,以便更快地执行 PHP 脚本。

    根据我的内存,我只能建议您检查与 RAM、硬盘驱动器访问、环境变量、限制和安全性(如防火墙)有关的所有内容。所有可能影响 php 脚本执行的东西,从一些远程过程调用策略开始,到操作堆栈内存结束。

    逻辑是 php.exe 调用一些外部 .dll 文件来执行某些操作,可能会检查操作系统完成的方式,这会减慢通过此类 .dll 发送请求和接收响应的速度。如果 .dll 使用硬盘驱动器访问某些东西 - 硬盘驱动器访问策略进入场景。此外,所有内容如何位于内存中 - 在 RAM 或 RAM 的硬盘驱动器缓存中。应用政策。线程策略。可用于应用程序的最大百分比限制。

    我并不是说基于 Windows 的主机不好,只是对于一般管理员来说,正确设置它们要困难得多。如果您有 Microsoft 专家,他可以将您的服务器调整为与基于 Linux 的服务器一样快。

    关于PHP factor 30 从 Linux 到 Windows 的性能差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22845321/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com