自定义CMS上可怕的Apache Bench结果

时间:2011-09-28 10:34:17

标签: apache benchmarking chunked-encoding apachebench http-chunked

请注意:这不是对伪劣CMS的抱怨。

只是玩弄Apache Bench并使用我们的自定义CMS获得了糟糕的结果,更确切地说,我得到了:

Requests per second:    0.37 [#/sec] (mean)

当我用普通的php文件运行另一个测试时,我得到了:

Requests per second:    4786.07 [#/sec] (mean)

使用以前版本的CMS进行的另一项测试:

Requests per second:    6068.66 [#/sec] (mean)

网站工作正常,没有检测到问题,谷歌的网站管理员工具报告我们的网站比80%的页面更快,我认为。

测试是:

ab -t 30 -c 10 http://example.com/

也许某种Apache问题?错误.htaccess配置或类似?

更新

刚刚使用套接字运行了一个简单的测试,结果很相似。页面加载非常非常缓慢。如果我用另一个网站运行我的脚本,一切都很好。

此外,还有一个关于块长度问题的small hint。 (Bad Apache标题或行结尾?)

网站被gzip压缩,当详细日志记录开启时,我在响应中看到这些行:

LOG: Response code = 200
LOG: header received:
HTTP/1.1 200 OK
Date: Tue, 04 Oct 2011 13:10:49 GMT
Server: Apache
Set-Cookie: PHPSESSID=ibnfoqir9fee2koirfl5mhm633; path=/
Expires: Sat, 26 Jul 1997 05:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Cache-Control: post-check=0, pre-check=0
Vary: Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

2ef6

始终位于HTML源代码的同一位置,然后再次<!DOCTYPE HTML>

请帮助。

更新#2:

刚刚使用Rex Swain's HTTP Viewer检查了我的HTTP标头并获得了以下结果:

HTTP/1.1·200·OK(CR)(LF)
Date:·Wed,·05·Oct·2011·08:33:51·GMT(CR)(LF)
Server:·Apache(CR)(LF)
Set-Cookie:·PHPSESSID=n88g3qcvv9p6irm1fo0qfse8m2;·path=/(CR)(LF)
Expires:·Sat,·26·Jul·1997·05:00:00·GMT(CR)(LF)
Cache-Control:·no-store,·no-cache,·must-revalidate(CR)(LF)
Pragma:·no-cache(CR)(LF)
Cache-Control:·post-check=0,·pre-check=0(CR)(LF)
Vary:·Accept-Encoding(CR)(LF)
Connection:·close(CR)(LF)
Transfer-Encoding:·chunked(CR)(LF)
Content-Type:·text/html;·charset=UTF-8(CR)(LF)
(CR)(LF)

你注意到什么异常吗?

1 个答案:

答案 0 :(得分:4)

如果它适用于普通的Web浏览器(正如您在评论中提到的那样),CMS会以不同的方式处理来自Apache Benchmark的请求。

快速核对清单:

  • AFAIK Apache Benchmark只发送简单请求而不进行任何cookie处理,因此请尝试使用有效的cookie设置-C(从Web浏览器复制值)。
  • 尝试向网络浏览器发送完全相同的标头发送到CMS。使用netcat,HttpFox或数据包嗅探器保存有效请求的转储,并使用-H设置缺少的标头。
  • 在您向Apache Benchmark发送请求时,在服务器上配置CMS。也许你找到了瓶颈。在index.php(或测试脚本的入口点)的第一行和最后一行中有两个带有时间戳的穷人error_log调用可以显示PHP脚本的速度有多快并有助于计算开销的开销。 Apache HTTP Server和网络。
  • 如果您从不同的计算机上运行套接字测试和浏览器测试,则可能是DNS问题(在Apache中关闭HostnameLookups)。尝试从同一台机器运行它们。
  • 尝试ab -k ...ab -H "Connection: close" ...

我猜CMS在初始化会话时会进行一些代价高昂的初始化,并且在处理第一个请求时会发生。由于Apache Benchmark不会将cookie发送回CMS,因此会为每个请求创建一个新会话,这是导致答案缓慢的原因。

第二个猜测是CMS以不同的方式处理传入的http标头,而Apache Benchmark发送的标头(或缺少它们)会触发一些昂贵/缓慢的处理。自Google的网站管理员工具报告以来,它看起来更合适。


Apache Benchmark发送HTTP 1.0请求,例如:

GET / HTTP/1.0
Host: localhost:9100
User-Agent: ApacheBench/2.3
Accept: */*

在我看来,您的服务器不会发送任何有关Keep-Alive设置的http标头,但它假定客户端使用HTTP 1.0时客户端使用keep-alive。它不是符合RFC的行为:

来自RFC 2616, 19.6.2 Compatibility with HTTP/1.0 Persistent Connections

  

某些客户端和服务器可能希望与某些客户端和服务器兼容   以前在HTTP / 1.0中实现持久连接的方法   客户和服务器。 HTTP / 1.0中的持久连接是
  明确协商,因为它们不是默认行为。

默认情况下,Apache Benchmark不使用keep-alive,因此它会在响应关闭套接字时等待。服务器在闲置15秒后关闭它。使用wget下载主页也需要15秒。 Wget还在请求中使用HTTP 1.0。

我认为这是CMS的PHP代码中的一个错误,因为ab在具有普通php文件的同一服务器上运行良好。无论如何,您可以使用保持活动连接(-k)来解决它:

ab -k -t 30 -c 10 http://example.com/

或明确禁用持久连接:

ab -H "Connection: close" -t 30 -c 10 http://example.com/

但它仍然是服务器端问题,而您原来的ab命令是正确的。

请注意,此错误可能仅影响HTTP 1.0客户端(如Apache Benchmark,wget),而常规浏览器的客户端也不会注意到它。