WeTest 导读
在服务上线之前, 性能测试必不可少. 本文主要介绍性能测试的流程, 需要关注的指标, 性能测试工具 apache bench 的使用, 以及常见的坑.
什么是性能测试
性能测试是通过自动化的测试工具模拟多种正常, 峰值以及异常负载条件来对系统的各项性能指标进行测试. 负载测试和压力测试都属于性能测试, 两者可以结合进行. 通过负载测试, 确定在各种工作负载下系统的性能, 目标是测试当负载逐渐增加时, 系统各项性能指标的变化情况. 压力测试是通过确定一个系统的瓶颈或者不能接受的性能点, 来获得系统能提供的最大服务级别的测试.
性能测试的目标是什么
性能测试最终的目的, 是找到系统的瓶颈, 一般来说, 是找到服务单机最大 TPS(每秒完成的事务数).
需要注意的是, 服务的 TPS 需要结合请求平均耗时来综合考虑. 例如: 服务 TPS 压到 1000, 平均请求耗时 500ms, 但是假如我们定的服务请求耗时不能超过 200ms, 那么这个 1000 的 TPS 是无效的.
很多场景下, 服务都会设置超时时间, 若平均耗时超过此超时时间, 则可认为服务处于不可用状态.
什么时候需要性能测试
1. 功能测试完成之后, 上线之前.
正常情况下, 上线之前, 都应该进行性能测试, 尤其是请求量较大的接口, 重点业务的核心接口, 以及直接影响用户操作流程的接口.
2. 各种大促, 运营活动开始之前.
大促, 运营活动, 都会导致流量激增, 因此上线之前做好压力测试, 评估系统性能是否满足预估流量, 提前做好准备.
举个反面例子: 聚美优品, 年年大促年年挂.
再来个正面的例子: 每年双十一之前, 阿里都会有全链路压测, 各个业务自己也会有独立的压测, 阿里在这块做得还是非常不错的.
怎么做性能测试
常见的 http 性能测试工具
1. httpload
2. wrk
3. apache bench
最终我们选择 apache bench
看上去 wrk 才是最完美的, 但是我们却选择了 ab. 我们验证过各种工具请求数据是否准确, 压测的时候, 通过后台日志记录, 最终得出结论, ab 的请求数误差在千分之二左右, 而其他两个工具在千分之五左右.
不过不得不说, wrk 的确是一款非常优秀的压测工具, 采用异步 IO 模型, 能压到非常高的 TPS. 曾经用空逻辑接口压到过 7w 的 TPS, 而相同接口, ab 只能压到 2w 多.
apache bench 的使用
前面已经给了一个简单的例子了, 下面详细介绍下 ab 的使用.
如何安装? 如果 docker 容器已经安装的 apache, 那么恭喜, ab 是 apache 自带的一个组件, 不用重新安装了. 当然, 也可以自己单独安装 apache bench.
ab 常用参数介绍
参数说明:
格式: ab [options] [http://]hostname[:port]/path
- -n requests Number of requests to perform // 本次测试发起的总请求数
- -c concurrency Number of multiple requests to make // 一次产生的请求数 (或并发数)
- -t timelimit Seconds to max. wait for responses // 测试所进行的最大秒数, 默认没有时间限制.
- -r Don't exit on socket receive errors. // 抛出异常继续执行测试任务
- -p postfile File containing data to POST // 包含了需要 POST 的数据的文件, 文件格式如 "p1=1&p2=2". 使用方法是 -p 111.txt
- -T content-type Content-type header for POSTing
- //POST 数据所使用的 Content-type 头信息, 如 -T "application/x-www-form-urlencoded" . (配合 - p)
- -v verbosity How much troubleshooting info to print
- // 设置显示信息的详细程度 - 4 或更大值会显示头信息, 3 或更大值可以显示响应代码 (404, 200 等), 2 或更大值可以显示警告和其他信息. -V 显示版本号并退出.
- -C attribute Add cookie, eg. -C "c1=1234,c2=2,c3=3" (repeatable)
- //-C cookie-name=value 对请求附加一个 Cookie: 行. 其典型形式是 name=value 的一个参数对. 此参数可以重复, 用逗号分割.
提示: 可以借助 session 实现原理传递 JSESSIONID 参数, 实现保持会话的功能, 如 - C " c1=1234,c2=2,c3=3, JSESSIONID=FF056CD16DA9D71CB131C1D56F0319F8″ .
- -w Print out results in html tables // 以 HTML 表的格式输出结果. 默认时, 它是白色背景的两列宽度的一张表.
- -i Use HEAD instead of GET
- -x attributes String to insert as table attributes
- -y attributes String to insert as tr attributes
- -z attributes String to insert as td or th attributes
- -H attribute Add Arbitrary header line, eg. 'Accept-Encoding: gzip' Inserted after all normal header lines. (repeatable)
- -A attribute Add Basic WWW Authentication, the attributes
- are a colon separated username and password.
- -P attribute Add Basic Proxy Authentication, the attributes are a colon separated username and password.
- -X proxy:port Proxyserver and port number to use
- -V Print version number and exit
- -k Use HTTP KeepAlive feature
- -d Do not show percentiles served table.
- -S Do not show confidence estimators and warnings.
- -g filename Output collected data to gnuplot format file.
- -e filename Output CSV file with percentages served
- -h Display usage information (this message)
性能测试报告
测试报告应该包含以下内容. 当然, 根据场景不同, 可以适当增减指标, 例如有的业务要求关注 CPU, 内存, IO 等指标, 此时就应该加上相关指标.
常见的坑
1.AB 发送的是 http1.0 请求.
2.-t 可以指定时间,-n 指定发送请求总数, 同时使用时压测会在 - t 秒或者发送了 - n 个请求之后停止. 但是 - t 一定要在 - n 之前 (ab 的 bug,-n 在 - t 之前最多只会跑 5s).
3. 为了使测试结果更可靠, 单次压测时间应在 2 分钟以上.
理论上, 压测时间越长, 结果误差越小. 同时, 可以在瓶颈附近进行长时间压测, 例如一个小时或者一天, 可以用来测试系统稳定性. 许多系统的 bug 都是在持续压力下才会暴露出来.
4. 小心压测客户端成为瓶颈.
例如上传, 下载接口的压测, 此时压测客户端的网络上行, 下行速度都会有瓶颈, 千万小心服务器还没到达瓶颈时, 客户端先到了瓶颈. 此时, 可以利用多客户端同时压测.
5.ab 可以将参数写入文件中, 用此种方式可以测试上传文件的接口.
需要配合 - p -t 使用.
$ ab -n 10000 -c 8 -p post_image_1k.txt -T "multipart/form-data; boundary=1234567890" http://xxxxxxx
文件内容如下:
6.ab 不支持动态构建请求参数, wrk 可配合 lua 脚本支持动态构建请求参数, 还是比较牛的.
- package.path = '/root/wrk/?.lua;'
- local md5 = require "md5"
- local body = [[BI_login|userid{145030}|openid{4-22761563}|source{}|affiliate{}|creative{}|family{}|genus{0}|ip{180.111.151.116}|from_uid{0}|login_date{2016-11-04}|login_time{10:40:13}|extra{}|srcid{1}|snid{1002}|clientid{1253}|gameid{2100012}
- BI_logout|userid{184103}|openid{4-22784181}|family{}|genus{0}|ip{218.2.96.82}|logout_date{2016-11-04}|logout_time{10:40:42}|extra{}|srcid{1}|snid{1002}|clientid{1253}|gameid{2100012}
- BI_role_logout|roleid{184103}|userid{184103}|openid{4-22784181}|ip{218.2.96.82}|level{100}|money{468}|power{1}|exp{252}|lijin{0}|online_time{0}|mapid{0}|posx{0}|posy{0}|rolelogout_date{2016-11-04}|rolelogout_time{10:40:42}|extra{0}|srcid{0}|snid{1002}|clientid{1253}|gameid{2100012}
- BI_logout|userid{71084}|openid{4-20974629}|family{}|genus{0}|ip{117.136.8.76}|logout_date{2016-11-04}|logout_time{10:40:43}|extra{}|srcid{1}|snid{1002}|clientid{1253}|gameid{2100012}]]
- --local body = "hello"
- wrk.headers["Content-Type"] = "text/xml"
- local i=0
- request = function()
- i = i+1
- local path = "/v1/pub?gameid=510038×tamp=%s&key=510038&type=basic&sign=%s"
- local time = os.time()*1000
- local v = "510038" .. time .. "basic98889999"
- local sign = md5.sumhexa(v)
- path = string.format(path, time, sign)
- --print(path)
- return wrk.format("POST", path, nil, body)
- end
腾讯 WeTest 推出的 "压测大师", 一分钟完成用例配置, 无需维护测试环境, 支持 http 协议, API 接口, 网站等主流压测场景.
点击: https://wetest.qq.com/gaps 即可体验.
如果使用当中有任何疑问, 欢迎联系腾讯 WeTest 企业 QQ:2852350015.
来源: https://www.cnblogs.com/wetest/p/9756179.html