Fge*_*Fge 37 php linux windows wordpress performance
我们的团队正在开发WordPress插件,并在几个独立的服务器上提供托管实例.我们的WordPress安装由Git管理,所有服务器都部署了相同的源和WordPress设置,只有数据库中的域和实际数据不同.对于每个安装,MySql都在同一主机上运行.WordPress专门在每台服务器上运行.
但是,在Windows Server 2008 RC2上部署此设置后,我们发现与其他服务器相比,性能差异显着:页面生成时间从平均值上升.使用PHP生成的页面为400ms到4000-5000ms.对于Apache提供的静态资源,速度与linux上的速度大致相同.
所以我们采取了一些措施来缩小问题范围:
经过一些分析后,我们很快发现我们的Windows机器上正则表达式的评估速度非常慢.评估10.000正则表达式(preg_match
)在Linux上大约需要90ms,在Windows上需要3000ms.
下面提供了分析,系统测试和配置细节.我们不想优化这个脚本(我们知道该怎么做).我们希望脚本在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)
Run Code Online (Sandbox Code Playgroud)
更新2:某些原因我不记得我们回到激活PHP作为我们服务器上的Apache模块(同样会导致性能不佳).但今天他们跑得非常快(约1秒/请求).添加Opcache可以将其降低到~400ms/req.Apache/PHP/Windows保持不变.
1)分析结果
在所有机器上使用XDebug进行分析.通常我们只收集了一些运行 - 这些足以显示大部分时间(50%以上)花费的位置:[get_browser][1]
WordPress插件的方法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
}
Run Code Online (Sandbox Code Playgroud)
此功能类似于PHP,可get_browser
检测浏览器的功能和操作系统.大多数脚本执行时间都花在这个foreach
循环中,评估所有这些preg_match
(每页请求大约8000 - 10000).这在Linux上大约需要90ms,在Windows上需要3000ms.所有测试设置的结果都相同(图片显示了两次执行的数据):
当然,加载两个巨大的阵列需要一些时间.也评估正则表达式.但我们希望它们在Linux和Windows上花费大致相同的时间.这是linux vm上的分析结果(仅限一页请求).差异非常明显:
另一个时间杀手实际上是Object-Cache 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;
}
Run Code Online (Sandbox Code Playgroud)
时间花在这个函数本身(3个脚本执行):
在linux上:
最后一个真正的大时代杀手是翻译.从内存加载的每个翻译在WordPress中从0.2ms到4ms不等:
在linux上:
2)经过测试的系统
为了确保虚拟化或Apache确实影响了这一点,我们在几个设置上对此进行了测试.所有设置都禁用了Antivir:
如上所述的分析结果在不同系统上是相同的(~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)
Run Code Online (Sandbox Code Playgroud)
这发生在随机脚本位置.显然,Zend内存管理器无法分配更多内存,尽管允许脚本这样做.当事件发生时,服务器有大约50%的空闲RAM(2GB +).所以服务器实际上没有用完ram.重启Apache/PHP现在解决了这个问题.
不确定此问题是否与此处的性能问题有关.然而,由于这两个问题似乎都与记忆有关,因此将其纳入此处.特别是我们将尝试重现提供良好性能的Windows-Tests的设置.
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"
Run Code Online (Sandbox Code Playgroud)
mpm_winnt_module
组态:
<IfModule mpm_winnt_module>
ThreadsPerChild 150
ThreadStackSize 8388608
MaxConnectionsPerChild 0
</IfModule>
Run Code Online (Sandbox Code Playgroud)
php.ini的摘录:
realpath_cache_size = 12M
pcre.recursion_limit = 100000
Run Code Online (Sandbox Code Playgroud)
4)目前可疑的原因
旧假设:
这三个例子都很大程度上依赖于大数组和字符串操作.某种似乎是常见的工厂.由于Linux上的实现工作正常,我们怀疑这是Windows上的内存问题.鉴于在指针位置没有数据库交互,我们不怀疑数据库或服务器< - > PHP集成是问题.不知何故,PHP的内存交互似乎很慢.也许有人干扰Windows上的内存使访问速度显着降低?
旧假设2:
由于同一堆栈在其他Windows机器上运行良好,我们认为问题出在Windows配置中.
新假设3:
其实我没有假设.为什么运行PHP会像fastcgi那样慢得多,因为apache模块>
有关如何验证这个或在这里找到真正问题的任何想法?任何有关解决此问题的帮助或指示都非常受欢迎.
Windows在许多情况下都有许多限制,防止,保护,控制和使用计算机的服务/策略.
一位优秀的Microsoft认证专家将能够在几分钟内解决您的问题,因为他们将有经验确切地说明要检查和禁用/启用/更改设置的设置/服务/策略,以便更快地执行PHP脚本.
出于我的记忆,我只建议你检查所有涉及RAM,硬盘访问,环境变量,限制和安全性(如防火墙)的内容.所有可能影响php脚本执行的东西,从一些远程过程调用策略开始,到操作堆栈内存结束.
逻辑是,php.exe调用一些外部.dll文件来执行某些操作,可能会检查操作系统完成的方式,这将减慢通过此类.dll发送请求的速度,并从中接收响应.如果.dll使用硬盘驱动器访问某些内容 - 硬盘驱动器访问策略进入场景.此外,所有内容如何位于内存中 - 在RAM的RAM或硬盘驱动器缓存中.应用政策.线程策略.限制可用于应用程序的最大百分比.
我并不是说基于Windows的主机很糟糕,只是为普通管理员设置它们要困难得多.如果您手头有Microsoft专家,他可以将您的服务器调整为与基于Linux的服务器一样快.
归档时间: |
|
查看次数: |
15121 次 |
最近记录: |