Apache Bench和POST数据

13
我正在尝试使用Apache Bench来对我的Rails应用程序中的创建操作进行负载测试,但是ab似乎没有发送POST数据-尽管它确实提交了一个POST请求而不是GET请求。
这是我运行的命令:
ab -n 1 -p post -v 4 "http://oz01.zappos.net/registrations"

这是文章文件的内容:

authenticity_token=M18KXwSOuIVbDPZOVQy5h8aSGoU159V9S5uV2lpsAI0

Rails日志显示有一个POST请求,但没有显示任何被提交的参数:

Started POST "/registrations" for 10.66.210.70 at Thu Sep 09 17:48:06 -0700 2010
  Processing by RegistrationsController#create as */*
Rendered registrations/new.html.erb within layouts/application (14.0ms)
Completed 200 OK in 24ms (Views: 14.6ms | ActiveRecord: 0.1ms)

而来自浏览器的 POST 请求会导致此日志条目:

Started POST "/registrations" for 192.168.66.20 at Thu Sep 09 17:49:47 -0700 2010
  Processing by RegistrationsController#create as HTML
  Parameters: {"submit"=>"true", "authenticity_token"=>"AfNG0UoTbJXnxke2725efhYAoi3ogddMC7Uqu5mAui0=", "utf8"=>"\342\234\223", "registration"=>{"city"=>"", "address"=>"", "name"=>"", "zip"=>"", "optin"=>"0", "state"=>"", "email"=>""}}
Rendered registrations/new.html.erb within layouts/application (13.7ms)
Completed 200 OK in 24ms (Views: 14.3ms | ActiveRecord: 0.1ms)

最后,这是关于该请求的 ab 日志:

---
POST /registrations HTTP/1.0
User-Agent: ApacheBench/2.0.40-dev
Host: oz01.zappos.net
Accept: */*
Content-length: 63
Content-type: text/plain


---

为什么它没有获取到POST数据?

如果"post"文件不存在,那么我会收到一个错误消息说找不到该文件,所以我至少知道它能找到文件...


我有一个几乎相同的问题,只不过这次是一个150k的文件,ab似乎只向我的脚本吐出80k的内容,导致它一直阻塞等待更多的IO,因为content-length。你那边有什么进展吗? - Jé Queue
2个回答

13
也许你需要使用man ab中提到的-T选项:
ab -n 1 -p post -v 4 -T application/x-www-form-urlencoded "http://oz01.zappos.net/registrations"

我用Django测试了一下,似乎Django并不关心内容类型标头(无论我是否使用-T选项,它都会显示POST的内容),但Rails可能需要它。


1
我在使用ab命令时遇到了类似的问题,即使加上了-T选项,我也不认为是它的原因。 - Jé Queue
同样的问题,我在修复内容类型中的一个拼写错误后,这个方法对我起作用了。已经修正答案。 - Thilo
1
我在向-T提供内容类型标头时出了问题,我的问题是'Content-Type:application/json'而不是只有application/json - Josh Vickery

9

虽然这是一个老问题,但为了其他在Stack Overflow上搜索的人,以下是我让它工作的方法。

一定要确保您的帖子文件已正确URL编码,并且没有多余的非打印字符或结尾。最无误的方式就是使用代码创建它。我用Python创建了我的文件:

>>> import urllib
>>> outfile = open('post.data', 'w')
>>> params = ({ 'auth_token': 'somelongstringthatendswithanequalssign=' })
>>> encoded = urllib.urlencode(params)
>>> outfile.write(encoded)
>>> outfile.close()

示例输出:

auth_token=somelongstringthatendswithanequalssign%3D

2
你漏掉了负载测试部分 ;) - Glaslos
你是正确的。当然,您仍然需要使用新的、正确编码的post.data文件来实际运行ab。仅生成post.data文件对测试您的Web服务器(或任何其他应用程序)没有什么帮助... - Troy
1
在Python 3.8中,我需要这样做:from urllib.parse import urlencode,然后调用:encoded = urlencode(params) - alextsil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接