如果你是一位站长,随着自己苦心经营的网站越来越受欢迎,网站的流量与日俱增,那么,你是否了解自己的网站,最大能承受多少个用户同一时间对网站进行访问?如果网站长时间无法响应,或是响应速度太慢,这会导致有很多的抱怨接踵而至,比如:
1)春运时期,网上订购火车票的12306网站,只要一到放票的瞬间,服务器立马会超负荷的运行,经常会发生响应慢的情况,或者直接死给你看!
2)小米官网的抢购活动,一到12点开抢时间,小米服务器立刻进入崩溃的边缘,现象跟12306差不多。
题外话,现在小米官网针对抢购活动做了些调整,现在的抢购规则已经不是谁第一个点开网页,就能最先进入选购页面,现在添加了一个排队机制,其实就类似于摇号的过程,也可以理解为下边的抛骰子游戏:
a.如果抛不到六点->等待10秒钟,然后重新抛
b.如果此时手机售罄->程序会让你发扬愚公精神,一直重抛->直到过了十几分钟服务器更新缓存,才会给你提示手机售罄,此时活动结束,坑爹吧?
c.如果抛到六点->进入选购界面->如果此时手机售罄->提示对不起,没有库存了
d.如果抛到六点->进入选购界面->如果此时仍有库存->提示抢购成功
小米官网通过类似上边的处理机制,可以很大程度的缓解抢购狂潮对服务器造成的压力。
言归正传,无论什么情况,只要影响到用户的正常使用,都会让用户抱怨,严重的甚至会大量流失用户群,这很残酷,但很现实。
也许你认为现在还不是考虑这个问题的时候,但这是不可避免的,除非你有意向转行不干了。
那么,有没有什么方法能测试出,当有50、100或者更多的用户并发的访问网站的时候,自己的PHP程序会有怎么样的表现?
接下来就来介绍一个实用开源的网站压力测试工具,Apache Benchmark,简称ab。
下边介绍ab最简单的使用方法
1
|
ab www.baidu.com/
|
这就是ab最简单的测试命令,这一命令显示了百度页面的相关数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
Benchmarking www.baidu.com (be patient).....
done
Server Software:
/1
.0
Server Hostname:
Server Port:
Document Path:
Document Length:
Concurrency Level:
Time taken
for
tests:
Complete requests:
Failed requests:
Write errors:
Total transferred:
HTML transferred:
Requests per second:
#/sec] (mean)
Time per request:
Time per request:
Transfer rate:
/sec
] received
Connection Times (ms)
min
/-sd
] median
Connect:
Processing:
Waiting:
Total:
|
上边的数据中,HTML transferred
,Requests per second
,Time per request
是我们需要重点关注的,根据这些数据,我们能大概了解Web服务器的性能水平。
接下来给出相关字段说明:
Server Software | 服务器系统 |
Server Hostname | 服务器域名 |
Server Port | 服务器端口 |
Document Path | 访问的路径 |
Document Length | 访问的文件大小 |
Concurrency Level | 并发请求数,可以理解为同一时间的访问人数 |
Time taken for tests | 响应时间 |
Complete requests | 总共响应次数 |
Failed requests | 失败的请求次数 |
Write errors | 失败的写入次数 |
Total transferred | 传输的总数据量 |
HTML transferred | HTML页面大小 |
Requests per second | 每秒支持多少人访问 |
Time per request | 满足一个请求花费的总时间 |
Time per request | 满足所有并发请求中的一个请求花费的总时间 |
Transfer rate | 平均每秒收到的字节 |
最后的数据包括Connect,Processing,Waiting,Total字段。这些数据能大致说明测试过程中所需要的时间。其实我们可以只看Total字段中的min,max两列数据值,这两个值分别显示了测试过程中,花费时间最短和最长的时间。
ab命令还有很多可选参数,但常用的其实就下边三个:
参数 | 功能解释 |
-n | 设置ab命令模拟请求的总次数 |
-c | 设置ab命令模拟请求的并发数 |
-t | 设置ab命令模拟请求的时间 |
-k | 设置ab命令允许1个http会话响应多个请求 |
这三个参数的用法如下:
1)使用ab命令加上“-n”参数模拟1个用户访问百度总共5次
1
|
ab -n 5 www.baidu.com/
|
2)使用ab命令加上“-n”与“-c”参数模拟5个用户同时访问百度总共9次
1
|
ab -c 5 -n 9 www.baidu.com/
|
3)使用ab命令加上“-c”与“-t”参数模拟5个用户同时访问百度总共9秒
1
|
ab -c 5 -t 9 www.baidu.com/
|
3)使用ab命令加上“-c”与“-t”附加“-k”参数模拟5个用户同时访问百度总共9秒,百度会打开5个并发连接,从而减少web服务器创建新链接所花费的时间。
1
|
ab -c 5 -t 9 -k www.baidu.com/
|
使用ab命令的时候,有几点点要说明:
1)ab命令必须指定要访问的文件,如果没指定,那必须得在域名的结尾加上一个反斜杠,例如
1
|
ab www.baidu.com
|
得改写为
1
|
ab www.baidu.com/
|
2)ab命令可能会由于目标web服务器做了相应的过滤处理,导致在某些情况下收不到任何数据,这个时候可以使用“-H”参数,来模拟成浏览器发送请求。例如:
模拟成Chrome浏览器向百度发送1个请求
1
|
ab -H
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-Us) AppleWeb Kit/534.2 (KHTML, like Gecko) Chrome/6.0.447.0 Safari/534.2"
www.baidu.com/
|
3)最后,要注意的就是,在使用ab命令测试服务器时,千万要小心,并且要限制对服务器发出的请求数量,磨途歌希望大家理性使用这些压力测试工具,我们都不希望任何一台正常的服务器陷入不必要的麻烦。
更多的可选参数如下:
-A | 采用base64编码向服务器提供身份验证信息,用法: -A 用户名:密码 | |||||||
-C | cookie信息,用法: -C mo2g=磨途歌 | |||||||
-d | 不显示pecentiles served table | |||||||
-e | 保存基准测试结果为csv格式的文件 | |||||||
-g | 保存基准测试结果为gunplot或TSV格式的文件 | |||||||
-h | 显示ab可选参数列表 | |||||||
-H | 采用字段值的方式发送头信息和请求 | |||||||
-i | 发送HEAD请求,默认发送GET请求 | |||||||
-p | 通过POST发送数据,用法: -p blog=博客&mo2g=磨途歌 | |||||||
-P | 采用base64编码向服务器提供身份验证信息,用法: -A 用户名:密码 | |||||||
-q | 执行多余100个请求时隐藏掉进度输出 | |||||||
-s | 使用Https协议发送请求,默认使用Http | |||||||
-S | 隐藏中位数和标准偏差值 | |||||||
-v | -v 2 及以上将打印警告和信息,-v 3 打印http响应码,-v 4 打印头信息 | |||||||
-V | 显示ab工具的版本号 | |||||||
-w | 采用HTML表格打印结果 | |||||||
-x | HTML标签属性,使用 -w 参数时,将放置在标签中标签中
|
这一篇文章主要记录我在使用Apache Benchmark(一下检测ab)做网站压力测试的过程中,遇到的一些问题以及解决办法,方便日后使用.
Apache Benchmark简称为ab,是apache自带的用于HTTP Server测试的工具。它可以接受单一的URL,然后重复地按照指定的多个独立线程的方式加载,并使用不同的命令行参数控制访问的次数、最大的并发访问数等。
AB怎么用? -attributes ] [ -X proxy[:port] ] [ -y -attributes ] [ -z
语法
ab [ -A auth-username:password ] [ -c concurrency ] [ -C cookie-name=value ] [ -d ] [ -e csv-file ] [ -g gnuplot-file ] [ -h ] [ -H custom-header ] [ -i ] [ -k ] [ -n requests ] [ -p POST-file ] [ -P proxy-auth-username:password ] [ -q ] [ -s ] [ -S ] [ -t timelimit ] [ -T content-type ] [ -v verbosity] [ -V ] [ -w ] [ -x
-attributes ] [http://]hostname[:port]/path
选项
-A auth-username:password
向服务器提供基本认证信息。用户名和密码之间由一个":"隔开,并将被以base64编码形式发送。无论服务器是否需要(即是否发送了401认证需求代码),此字符串都会被发送。
-c concurrency
一次产生的请求个数。默认是一次一个。
-C cookie-name=value
对请求附加一个"Cookie:"头行。其典型形式是 name=value 的一个参数对。此参数可以重复。
-d
不显示"percentage served within XX [ms] table"消息(为以前的版本提供支持)。
-e csv-file
产生一个逗号分隔(CSV)文件,其中包含了处理每个相应百分比请求(从1%到100%)所需要的相应百分比时间(以微秒为单位)。由于这种格式已经"二进制化",所以比"gnuplot"格式更有用。
-g gnuplot-file
把所有测试结果写入一个"gnuplot"或者TSV(以Tab分隔)文件。此文件可以方便地导入到 Gnuplot, IDL, Mathematica, Excel中。其中的第一行为标题。
-h
显示使用方法的帮助信息。
-H custom-header
对请求附加额外的头信息。此参数的典型形式是一个有效的头信息行,其中包含了以冒号分隔的字段和值(如:"Accept-Encoding: zip/zop;8bit")。
-i
执行HEAD请求,而不是GET 。
-k
启用KeepAlive功能,即在一个HTTP会话中执行多个请求。默认不启用KeepAlive功能。
-n requests
在测试会话中所执行的请求个数。默认仅执行一个请求,此时其结果不具有意义。
-p POST-file
包含了POST数据的文件。
-P proxy-auth-username:password
对一个中转代理提供基本认证信息。用户名和密码由一个":"隔开,并将被以base64编码形式发送。无论服务器是否需要(即是否发送了407代理认证需求代码),此字符串都会被发送。
-q
如果处理的请求数大于150,ab每处理大约10%或者100个请求时,会在stderr输出一个进度计数。此 -q 标记可以屏蔽这些信息。
-s
用于编译中(ab -h 会告诉你)使用了SSL的受保护的https ,而不是http协议的时候。此功能是实验性的,最好不要用。
-S
不显示中值和标准偏差值,而且在均值和中值为标准偏差值的1到2倍时,也不显示警告或出错信息。默认时,会显示最小值/均值/最大值等数值。(为以前的版本提供支持)
-t timelimit
测试所进行的最大秒数。内部隐含值是"-n 50000"。它可以使对服务器的测试限制在一个固定的总时间以内。默认时,没有时间限制。
-T content-type
POST数据时所使用的"Content-type"头信息。
-v verbosity
设置显示信息的详细程度,4或更大值会显示头信息,3或更大值可以显示响应代码(404,200等),2或更大值可以显示警告和其他信息。
-V
显示版本号并退出。
-w
以HTML表格形式输出结果。默认时,它是白色背景的两列宽度的一张表。
-x-attributes
设置属性的字符串。此属性被填入。
-X proxy[:port]
对请求使用代理服务器。
-y -attributes
设置属性的字符串。
-z这一篇文章主要记录我在使用Apache Benchmark(一下检测ab)做网站压力测试的过程中,遇到的一些问题以及解决办法,方便日后使用。
1)当使用ab做压力测试,执行类似的命令:
1ab
-c 10 -n 10000 www.xxx.com/ 提示apr_poll: The timeout specified has expired (70007)或者apr_socket_recv: Connection timed out (110)。
解决方法:添加-k参数,压力测试命令改为“ab -c 10 -n 10000 -k www.xxx.com/”,如果问题依旧,那就得从linux服务器配置着手。向/etc/sysctl.conf配置文件添加下边的设置,主要调整net.ipv4.netfilter.ip_conntrack_max或nf_conntrack_max的值。
12345678910111213#kernel2.6之前的内核版本添加如下配置:
net.ipv4.netfilter.ip_conntrack_max
= 655360 net.ipv4.netfilter.ip_conntrack_tcp_timeout_established
= 1200 #kernel2.6之后的内核版本添加如下配置:
net.nf_conntrack_max
= 655360 net.netfilter.nf_conntrack_tcp_timeout_established
= 1200 net.ipv4.tcp_tw_recycle
= 0 #开启TCP连接中TIME-WAIT
sockets的快速回收,默认为0,表示关闭。 net.ipv4.tcp_tw_reuse
= 0 #开启重用,将TIME-WAIT
sockets重新用于新的TCP连接,默认为0,表示关闭; net.ipv4.tcp_fin_timeout
= 25 #修改系統默认的
TIMEOUT 时间 net.ipv4.tcp_orphan_retries
= 1 net.ipv4.tcp_max_orphans
= 8192 net.ipv4.ip_local_port_range
= 32768 61000
1sysctl
-p /etc/sysctl
.conf
#不重起服务器,让新配置生效
2)在用ab测试的时候,只要出现Failed requests(失败的请求),就会出现三种失败的类型统计:Connect、Length、Exception。
Connect:向服务器发送请求失败;服务器连接失败;请求过程连接中断等。
Length:服务器返回的数据长度不一致,一般是对比Content-Length的值。
Exception:与服务器连接过程中发生意外错误。
这里主要说明一下Length,ab会把第一次成功返回的content-length作为基准,如果后面的请求返回的content-length跟第一次的不一样,它就会把这次请求当成是失败了。对于动态类型的网站,每次服务器返回的数据都不一定相同,所以如果ab提示的是Length错误,基本都可以忽略掉。
3)默认情况下,ab没有启用gzip压缩功能,所以压力测试的结果会跟实际情况有很大的偏差。要想让ab使用gzip压缩功能,得添加参数 -H 'Accept-Encoding: gzip'
1ab
-H 'Accept-Encoding:
gzip' www.xxx.com/
4)带参数的压力测试示例
1
|
ab
'www.xxx.com/?a=1&b=2&c=3'
|
5)提示:Benchmarking 127.0.0.1 (be patient)...
如果出现这个问题,那很可能是你使用了apache2.4.1或以上的版本。似乎从2.4.*开始,就使用了ipv6的协议,另一种角度来说,这可能是一个bug,所以检测一下是不是以前把ipv6的相关服务给关了。开始菜单->控制面板->任务管理器->服务->启用IP Helper。
再检查一下文件C:\Windows\System32\drivers\etc\hosts,添加下边的对应关系。
1
|
::1
|
::1是ipv6中的IP地址,ipv4为127.0.0.1。
如果真是版本缺陷,我还是建议更换低版本的ab来使用。
-attributes 设置 | 属性的字符串。 |
在apache bin 目录,在linux上执行命令:
./ab -n 1 -v 4 -p 'userlogin.txt' -T 'application/x-www-form-urlencoded' 'http://api.xxxxx.com/1/login'
说明:
(1)
user_name=639493678400&password=A1111111&cheers=1
2)