【发布时间】:2011-09-03 14:47:32
【问题描述】:
我目前正在测试我正在组装的服务器设置的负载能力。 apache2 服务器上安装了 PHP 5.X,它连接到单独机器上的主数据库,然后连接到 2 个从服务器中的 1 个进行读取。
如果我自己调用它,我的测试页需要 0.2 秒才能生成。我在另一台服务器上创建了一个 php 脚本,它同时创建了 65 个对测试页面的调用。测试页面在整个页面中进行微时间基准测试,让我知道每个部分需要多长时间。正如预期的那样 - 至少对我来说,如果有人对此有意见或建议,请随时发表评论 - 页面的 SQL 部分需要很短的时间来处理它收到的前几个请求,然后降级,因为其余的查询堆积起来,必须等待。我认为这可能是磁盘 IO 问题,但在固态驱动器上测试时发生了同样的行为。
我的问题是大约 65 个页面中的大约 30 个已创建,并按我的预期由我的测试脚本加载。例如,我的基准测试说页面是在 3 秒内创建的,而我的测试脚本说它在 3.1 秒内收到了完整的页面。差别不大。问题是对于其他请求,我的基准测试表明页面在 3 秒内加载,但测试脚本直到 6 秒才完整接收到页面。从 apache 服务器生成的页面到发送回请求它的测试脚本之间有整整 3 秒的时间。为了确保测试脚本没有问题,我尝试在本地浏览器运行时加载页面,并通过 Chrome 中的时间线窗口确认了相同的延迟。
我已经为 Apache 尝试了各种配置,但似乎找不到导致此延迟的原因。我最近的尝试如下。该机器是具有 2Ghz 内存的四核 AMD 2.8Ghz。任何有关配置的帮助或其他有关操作的建议将不胜感激。 -- 抱歉问了这么长的问题。
我应该提到,我在脚本运行时监控了资源,CPU 达到了最大 9% 的负载,并且始终至少有 1 gig 的可用内存。
我还会提到,当我查询的只是一个静态 HTML 页面时,也会发生相同类型的事情。第一对需要 .X 秒,然后慢慢增加到 3 秒。
LockFile ${APACHE_LOCK_DIR}/accept.lock
PidFile ${APACHE_PID_FILE}
超时 120
最大客户数 150
保持活动状态
保活超时 4
MaxKeepAliveRequests 150
标头始终附加 x-frame-options sameorigin
启动服务器 50
MinSpareServers 25
MaxSpareServers 50
最大客户数 150
MaxRequestsPerChild 0
用户 ${APACHE_RUN_USER}
组 ${APACHE_RUN_GROUP}
AccessFileName .httpdoverride
命令允许,拒绝
DefaultType 文本/纯文本
主机名查找关闭
错误日志 ${APACHE_LOG_DIR}/error.log
日志级别警告
包括 mods-enabled/*.load
包括 mods-enabled/*.conf
包括 httpd.conf
包括 ports.conf
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" 组合
LogFormat "%h %l %u %t \"%r\" %>s %O" 常见
LogFormat "%{Referer}i -> %U" 引用
LogFormat "%{User-agent}i" 代理
包括 conf.d/
包括启用站点/
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
SecRuleEngine 开启
SecRequestBodyAccess 开启
SecResponseBodyAccess 关闭
SecUploadKeepFiles Off
SecDebugLog /var/log/apache2/modsec_debug.log
SecDebugLogLevel 0
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus ^5
SecAuditLogParts ABIFHZ
SecAuditLogType 串行
SecAuditLog /var/log/apache2/modsec_audit.log
SecRequestBodyLimit 131072000
SecRequestBodyInMemoryLimit 131072
SecResponseBodyLimit 524288000
服务器令牌已满
SecServerSignature "Microsoft-IIS/5.0"
更新: 似乎很多回应都集中在 SQL 是罪魁祸首这一事实上。所以我在这里声明相同的行为发生在静态 HTML 页面上。下面列出了基准测试的结果。
并发级别:10 测试时间:5.453 秒 完成请求:1000 失败的请求:899 (连接:0,接收:0,长度:899,例外:0) 写入错误:0 总传输量:290877 字节 传输的 HTML:55877 字节 每秒请求数:183.38 [#/sec](平均) 每个请求的时间:54.531 [ms](平均) 每个请求的时间:5.453 [ms](平均值,所有并发请求) 传输速率:收到 52.09 [Kbytes/sec] 连接时间(毫秒) 最小值平均值[+/-sd] 中值最大值 连接:0 21 250.7 0 3005 处理:16 33 17.8 27 138 等待:16 33 17.8 27 138 总计:16 54 253.0 27 3078 特定时间内服务的请求百分比(毫秒) 50% 27 66% 36 75% 42 80% 46 90% 58 95% 71 98% 90 99% 130 100% 3078(最长请求)我还要声明,我通过使用 PHP 和 microtime() 确定延迟是在页面生成之前发生的。我通过生成页面和我的测试脚本接收它之间的时间差来确定这一点。差异是一致的,这意味着从生成页面到我的测试页面收到它的时间量是相同的,无论整个请求花费了多长时间。
感谢所有回复的人。都是好点,我不能说他们中的任何一个都解决了这个问题。
【问题讨论】:
-
尝试更高的 StartServers 和 MinSpareServers。以我的经验,当流量突然爆发时,apache 可能需要一段时间才能启动额外的线程。在更宏大的计划中,通过快速反向代理 (nginx) 进行代理以更快地响应连接并更快地释放 apache 线程。更好的是,使用 squid/varnish 缓存页面,这样您就不会浪费资源数百次生成完全相同的内容。
-
啊,刚刚注意到关于数据库的一点。 1) 尽可能避免写入 2) 确定哪些查询正在减慢 3) 缓存以完全避免数据库访问。我会做一些基准测试——记录每个查询的查询时间,并生成所有运行查询的列表,在请求期间从最慢到最快排序。
-
好问题,只是属于不同的网站。
-
@AJ - 为什么它不属于这个网站?
-
@Frank: 1) 我正在做的唯一写入是基于内存的表。 2) 它实际上是在每页上运行 10 次完全相同的查询。从表 LIMIT 1000 中选择 *; 3)我增加了数据库服务器上的缓存,但由于某种原因它不想缓存它。在 apache 方面,1)我尝试通过反向代理并直接连接到机器,结果相同。 2)我可以缓存页面,但生产环境不会经常提供具有完全相同内容的页面,因此测试不会模拟实际使用情况。我会在一分钟内发布更高值的结果。