我最近把一个客户端的网站(使用concrete5 CMS)移到运行Gentoo,Apache 2.2,PHP5和MySQL 5的VPS上,我注意到Apache的响应时间相当糟糕(旧服务器上的响应时间相同) ,有时候可以达到8-9秒,但更多的是在300毫秒到3秒之间(对于300毫秒,我不介意)。 我知道这不是networking延迟,因为服务器的ping(从我的位置)大约30ms。
下面是一个时间的例子(你可以看到它在最初的等待之后很快):

我正在运行APC(虽然我不确定这是否正确) …和SuExec。 Apache模块是:
core_module (static) authn_file_module (static) authn_default_module (static) authz_host_module (static) authz_groupfile_module (static) authz_user_module (static) authz_default_module (static) auth_basic_module (static) include_module (static) filter_module (static) deflate_module (static) log_config_module (static) env_module (static) expires_module (static) headers_module (static) setenvif_module (static) version_module (static) ssl_module (static) mpm_prefork_module (static) http_module (static) mime_module (static) status_module (static) autoindex_module (static) asis_module (static) info_module (static) suexec_module (static) cgi_module (static) negotiation_module (static) dir_module (static) actions_module (static) userdir_module (static) alias_module (static) rewrite_module (static) so_module (static) suphp_module (shared)
和PHP模块是:
bcmath calendar ctype curl db dbase domxml exif ftp gd gettext iconv imap mbstring mcrypt mime_magic mysql openssl overload pcre posix session standard sysvsem sysvshm tokenizer xml xslt zlib
我已经在所有相关文件上启用了gzip。
Apache正在使用prefork来运行,httpd.conf中的设置是:
<IfModule prefork.c> StartServers 10 MinSpareServers 10 MaxSpareServers 20 MaxClients 250 MaxRequestsPerChild 4000 </IfModule> HostnameLookups Off
我注意到,(我认为)数据库很重的页面,比如CMS的Dashboard,通常会比较慢。 我认为这可能意味着MySQL可以被优化。 我也想知道Apache模块 – 我在mod_php5,mod_cgi,mod_fastcgi等等之间感到困惑 – 所有的networking都有相互矛盾的build议,以至于最好的使用。
这里是MySQLTuner的输出:
-------- General Statistics -------------------------------------------------- [--] Skipped version check for MySQLTuner script [OK] Currently running supported MySQL version 5.0.44-log [OK] Operating on 64-bit architecture -------- Storage Engine Statistics ------------------------------------------- [--] Status: -Archive -BDB -Federated -InnoDB -ISAM -NDBCluster [--] Data in MyISAM tables: 35M (Tables: 161) [!!] Total fragmented tables: 15 -------- Security Recommendations ------------------------------------------- [OK] All database users have passwords assigned -------- Performance Metrics ------------------------------------------------- [--] Up for: 3d 21h 44m 16s (293K q [0.868 qps], 1K conn, TX: 135M, RX: 90M) [--] Reads / Writes: 99% / 1% [--] Total buffers: 58.0M global + 1.6M per thread (100 max threads) [!!] Maximum possible memory usage: 219.7M (93% of installed RAM) [OK] Slow queries: 0% (0/293K) [OK] Highest usage of available connections: 2% (2/100) [OK] Key buffer size / total MyISAM indexes: 16.0M/20.9M [OK] Key buffer hit rate: 99.6% (5M cached / 21K reads) [!!] Query cache is disabled [OK] Sorts requiring temporary tables: 0% (0 temp sorts / 3K sorts) [!!] Temporary tables created on disk: 47% (2K on disk / 5K total) [!!] Thread cache is disabled [!!] Table cache hit rate: 6% (64 open / 1K opened) [OK] Open file limit used: 12% (128/1K) [OK] Table locks acquired immediately: 100% (356K immediate / 356K locks) -------- Recommendations ----------------------------------------------------- General recommendations: Run OPTIMIZE TABLE to defragment tables for better performance Reduce your overall MySQL memory footprint for system stability Enable the slow query log to troubleshoot bad queries When making adjustments, make tmp_table_size/max_heap_table_size equal Reduce your SELECT DISTINCT queries without LIMIT clauses Set thread_cache_size to 4 as a starting value Increase table_cache gradually to avoid file descriptor limits Variables to adjust: *** MySQL's maximum memory usage is dangerously high *** *** Add RAM before increasing MySQL buffer variables *** query_cache_size (>= 8M) tmp_table_size (> 32M) max_heap_table_size (> 16M) thread_cache_size (start at 4) table_cache (> 64)
我注意到当一个数据库重载的页面被加载时,CPU使用率猛增到57%(使用最高) – 对我来说,这表明有一些严重优化的MySQL的东西或caching是绝对必要的,以加快这个设置。
任何帮助将不胜感激!
你确切知道apache工作进程正在被挂起吗? 试试看看:
mkdir /strace; ps auxw | grep httpd | awk '{print"-p " $2}' | xargs strace -o /strace/strace.log -ff -s4096 -r
在浏览器中加载一些新的(即不是本地caching的)页面,CTRL + C停止strace,然后按每次调用花费的时间sortingstrace.logs:
for i in `ls /strace/*`; do echo $i; cat $i | cut -c11-17 | sort -rn | head; done
查看超过1.0秒调用的任何strace.log,并根据上一个命令的输出时间进行search。 这将指出你正在进入的确切步骤。
你有没有像CSF安装防火墙? 我在VPS上看到了同样的问题。 使用stracedebugginghttpd进程时,gettimeofday调用需要5秒或更长的时间。 奇怪的是,我缩小到CSF,试图过滤venet0接口,OpenVZ或Virtuozzo容器中的回送接口。 在/etc/csf/csf.conf中设置这个参数主要是为我修复的:
"ETH_DEVICE_SKIP = "venet0,lo"
主要是因为有时候还有500-1000ms等待连接build立,但是从5000+开始有了很大的改进。
这是使用strace对这些问题进行故障排除的一个很好的入门/步骤 。
Maximum possible memory usage: 219.7M (93% of installed RAM)
这必须是一个低端的VPS盒子?
你必须拆分networking,Apache,MySQL和PHP作为延迟的来源。
如果你能从apache快速地(从非常低的时间到第一个字节)提取图片,那么networking和apache通常都很好。
如果你只需要一个phpinfo()语句,那么通常的PHP就可以了(可能需要一些调整)。
如果你写一个简单的数据库连接testing,并且速度很快,那么这个层通常也可以。
最后,拉应用程序页面。 如果速度慢,那么这个问题就是应用程序处理的内部问题。 虽然调优可能有所帮助,但要解决起来要困难得多。
不分析应用程序,可能很难find问题。 像NewRelic这样的工具可以帮助解决这个问题,但不是一种解决办法。
你的应用程序是否有任何types的内部debugging,以显示在哪里花费时间?
我build议添加一个渲染时间测量,并检查服务器渲染纯HTML页面需要多长时间。 那么你知道它是否在CMS或其他地方。 我打赌我的2cent不是你的服务器configuration。 / maddin