Rails Apache Benchmark 的使用的个人浅薄经验

killyfreedom · 2013年09月03日 · 最后由 wang3feng 回复于 2013年09月30日 · 30418 次阅读
本帖已被管理员设置为精华贴

之前为了 bench node 和 ruby 在 EM 环境下的性能差距,写了一个帖子,之后有人问我是如何使用工具来评测 http 服务的并发性能的,于是乎就总结了下自己是如何使用 apache benchmark 的经验,懂得技术大牛就呵呵一过,不知道或者有点了解的大家就一起讨论讨论。

apache benchmark作为apache旗下的 http server 的性能评测工具,个人觉得是非常简单非常好用的一个东西的,而且,在大并发的情况下,并不会吃掉太多性能,个人用起来觉得还是很爽的。

安装方式

Linux: sudo apt-get install apache2-utils MacOS: 装了 XCODE 或者 XCODE 的命令行工具之后就自然有了

使用

一般最简单的使用方式是:ab -c 并发数量 -n 总数量 url的方式,具体很多参数可以参照帮主文档 man ab 或者 ab -h

授人以鱼不如授人以渔

值得提醒的是对于那些需要上下文的请求,可以使用 ab 的 cookie 的参数来设置 cookie 值从而达到在保存了登录状态的上下文的情况下测试性能

通常,我们被测试的机器和测试的机器往往不在一台物理服务器上,如果在一台物理服务器上,测试和服务的提供是会产生影响的,毕竟 CPU 在进程间切换是会带来很大的性能损耗的,如果做严谨的测试,不推荐在一台服务器上做这个事情

输出 当你尝试编辑 bench 了一个 url 之后,往往会得到很多输出,比如

This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        
Server Hostname:        127.0.0.1                        
Server Port:            4001                                    

Document Path:          /
Document Length:        0 bytes

// 以上是你打压力的host, port等一部分的信息, 应该都看得懂把...

Concurrency Level:      100
// 这个标志了这1000个请求完成了总共消耗了这些时间
Time taken for tests:   2.987 seconds 
Complete requests:      1000
// 这1000个请求中失败的次数,如果又失败,它也有输出非2XX的失败
// 如果测试中出现了错误,最好看下这些错误是不是你所期望的
Failed requests:        0
Write errors:           0
// 这1000个请求总共传输了这些数据
Total transferred:      637272 bytes
HTML transferred:       0 bytes
// 每秒执行了334个请求,这个可以看到你服务器每秒能够处理多少个这样的url请求
// 是一个很重要的性能指标
Requests per second:    334.74 [#/sec] (mean)
// 第一个时间是以你的并发数为一组,这里我是设置了并发100,那么
// 就是这一组请求所能消耗的总时间
Time per request:       298.739 [ms] (mean)
// 这个就是平均下来每个请求的消耗的时间了
Time per request:       2.987 [ms] (mean, across all concurrent requests)
// 测试的时候通过网络的传输的速率
Transfer rate:          208.32 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.6      0       3
Processing:    24  297 780.6     39    2648
Waiting:       23  295 780.5     36    2646
Total:         25  298 781.1     39    2650
// 以上这段数据标志了一个请求从连接,发送数据,接收数据这个三个大致的时间,最小以及平均值


Percentage of the requests served within a certain time (ms)
  50%     39
  66%     40
  75%     41
  80%     41
  90%   2624
  95%   2647
  98%   2650
  99%   2650
 100%   2650 (longest request)

// 以上的数据标志了所有的api请求的消耗时间分布的区间
// 可以看到, 50%的请求是在39MS以下, 66%的请求实在40MS一下
// 这个数据其实可以看出很多问题来
//       如果这个数据很平均,即第二列的数据的值几乎都差不多,其实可以说明,至少
//       你的服务器在这个并发的情况下对于各个请求所能提供的能力是均衡的
//       在面对这种压力的并发的情况下,对资源没有明显的使用短缺
//       如果这个数据的差距非常大,这个情况就要结合自身的应用分析了
//       就像现在这种情况,可以发现,明显有一部分请求在很久之后才得到响应
//       说明,在并发的情况下,CPU或者IO或者其它资源没有被均衡的使用

我尝试解析了下这个输出,如有不对的地方也请大家指出呐

还有就是个人经验,对于 api 服务器来说,重要的不是单个请求处理的有多快,而是 在同一段时间能够处理多少请求 这一段时间在各个场景下的解读,往往能够影响整个服务的设计

我就是那个发邮件求写攻略的人!为了大家我真是拼了!

#2 楼 @killyfreedom 不要谦虚,写的很好

ab 只能用 ip 访问,不能测 post 请求,在 mac 上有文件描述符数量的问题 (一开多就会卡住)

wrk 就可以,资源消耗比 ab 更少一点所以更准 (不过在 mac 也有点小 bug)

brew install wrk

好东西。小弟也写了个关于 gem 开发的想法,也分析了下 faker 的源码,不知道有无人想知道。。。害羞的不敢说话。

#6 楼 @xstmjh 先找个工作再说。。。

@xstmjh 发出来工作就好找了

@realwol 随便写,写得好大家收益,写的不好有人指导,稳赚的事情呀

@luikore 嗯,有时间看一下,ab 也可以 post 的吧,postfile...

不在本机测试的话网络会对结果有影响么?

@guyanbiao 相对来说,如果在内网环境下,不在本机测试反而更加准确的可以体现性能,毕竟,api 服务器大多数都是通过 tcp 访问的

不知道 Failed requests 是否意味着有那么多次没有请求成功?

@huacnlee 应该是的,它判断是否失败应该是基于 http response code 的

这个数据里,80 分位和 90 分位之间有一个明显的跳跃,从 41ms 到 2.6s,有没有查到是什么原因?

#4 楼 @luikore wrk 的文档太少了点吧。。。post 的时候 参数该怎么写都不说明一下

#18 楼 @googya

直接 wrk 就能看到选项的,很简单

Usage: wrk <options> <url>
  Options:
    -c, --connections <N>  Connections to keep open
    -d, --duration    <T>  Duration of test
    -t, --threads     <N>  Number of threads to use

    -H, --header      <H>  Add header to request
    -M, --method      <M>  HTTP method
        --body        <B>  Request body
        --latency          Print latency statistics
        --timeout     <T>  Socket/request timeout
    -v, --version          Print version details

  Numeric arguments may include a SI unit (1k, 1M, 1G)
  Time arguments may include a time unit (2s, 2m, 2h)

例:

wrk -M POST -H "Content-Type: application/x-www-form-urlencoded" --body "foo=bar&baz=xip" http://localhost/

#19 楼 @luikore 嗯,刚才看了它的 issues 之后,有人也提供了类似的写法了。。https://github.com/wg/wrk/issues/24

#10 楼 @killyfreedom 恩,恩,知道了,正在写。

用过 JMeter,压力测试工具,也不错

一直有个疑问:如果用类似的压力测试工具,去对网站进行大规模测试,不会影响到网站处理其他用户正常的请求吗?

#24 楼 @whh 测试用的是测试环境

#24 楼 @whh 😄 这个可以用来干坏事。。

#24 楼 @whh 确实,不过,跟你的带宽也有关系,太小了,对别人影响不大

#4 楼 @luikore ab 可以用域名和发 post 请求啊 D:>ab -n 1000 -c 100 -p post.txt -T "application/x-www-form-urlencoded" http://xx.xxx.com/xxxx 我用的是 windows 下的,难道有不同?

#28 楼 @kiol mac 下以前不能 -_- 还有各种 bug

#27 楼 @tinyfool 你这个头像很销魂阿,不像你风格。

ibugs MongoDB 与 MySQL 深入对比 提及了此话题。 02月22日 16:54
需要 登录 后方可回复, 如果你还没有账号请 注册新账号