基本概念数据库
开始前,先简单介绍一下性能测试的几个基本概念。后端
并发数缓存
并发数是指在同一个时间点,同时请求服务的客户数量。服务器
好比你们常说的:『 个人网站能够承受一万并发。 』在一般状况下指的是:若是同时有一万名用户访问网站,全部人均可以正常得到服务。而不会有超时或链接拒绝状况发生。网络
吞吐率并发
吞吐率指的是服务处理请求的效率,计算方式为 ( 总处理请求数 / 总耗时 )。负载均衡
HTTP 服务的吞吐率一般以 RPS(Requests Per Second 请求数每秒)做为单位。吞吐量越高,表明服务处理效率就越高。换句话说就是网站的性能越高。工具
注意:吞吐率和并发数是两个彻底独立的概念。拿银行柜台来举个例子,并发数指同时有多少人往银行柜台涌来。吞吐率则指银行柜台在一段时间内能够服务多少我的。性能
可是在性能测试中,两者之间一般会呈现出一种关联关系。当并发数增大时,吞吐率一般也会随之上升( 多用户发挥出并行处理优点) 。但在并发数超过某个边界值后,吞吐率则会降低 (用户过多,花在上下文切换的开销急剧增大,又或者内存消耗过多) 。测试
响应时间
响应时间指的是用户从发出请求到接收完响应之间的总耗时,它由网络传输耗时、服务处理耗时等多个部分组成。一般以毫秒(ms)做为单位。
与并发数的关系:通常来讲,随着并发数增大,单个用户的响应时间一般会随之增长。这很好理解,餐馆吃饭的人越多,单个顾客等待的时间就越长。
与吞吐率的关系:更高的吞吐率一般意味着更低的响应时间。由于吞吐率是以 单位时间 内的请求处理能力来计算的。
平均响应时间与百分位响应时间
平均响应时间指的是全部请求平均花费的时间,若是有100个请求,其中 98 个耗时为 1ms,其余两个为 100ms。那么平均响应时间为 (98 * 1 + 2 * 100) / 100.0 = 2.98ms 。
百分位数( Percentile - Wikipedia )是一个统计学名词。以响应时间为例, 99% 的百分位响应时间 ,指的是 99% 的请求响应时间,都处在这个值如下。
拿上面的响应时间来讲,其总体平均响应时间虽然为 2.98ms,但 99% 的百分位响应时间倒是 100ms。
相对于平均响应时间来讲,百分位响应时间一般更能反映服务的总体效率。现实世界中用的较多的是 98% 的百分位响应时间,好比 GitHub System Status 中就有一条 98TH PERC. WEB RESPONSE TIME 曲线。
准备工做
1. 挑选测试目标
一个网站一般有不少个不一样的页面和接口。若是要彻底模拟真实环境的访问,就得为各页面设置不一样的权重,同时访问全部页面。或者取巧一点,采用重放真实环境访问记录的方式。
进行总体性能测试比较复杂,这里不打算介绍相关内容。 此次主要讨论对单个页面测试。
那么,怎么挑选测试的目标页面呢?通常来讲,那些用户访问较多的页面一般是比较好的选择,它们多是:
· 首页/Landing Page :一般是用户第一个打开的页面
· 关键行为页面 :若是网站的主要功能是发放优惠券,那就测试发放优惠券的接口
· 活动页面 :新活动上线推广前,理所应当应该进行性能测试
尽可能模拟真实的用户状况
举个例子,若是你想压测一个文章列表页,那么必定先要挑选一位拥有必定数量文章的用户,而后使用其身份来进行测试。千万不要用那些一篇文章没有、或只有少数文章的测试帐号。那样会产生失真的测试结果,让你对服务能力产生过于乐观的估计。
因此,在测试与用户相关的动态内容时,请细心挑选用户身份,尽可能反映绝大多数用户的状况。
别忘了关注边界状况
让测试过程反映绝大多数用户的状况很重要,但也请别忘了那些边界状况。
好比,当用户拥有 50 篇如下的文章时,你的文章列表页面响应速度很是好,吞吐率很是高。那么若是某个用户拥有 1000 篇文章呢?列表页的性能表现还能知足需求吗?响应时间会不会呈指数级上升?这些都是你须要测试的。
牢记『木桶效应』,你的服务极可能会由于没有处理好这些边界状况而崩溃。
2. 选择测试工具
市面上开源的 HTTP 性能测试工具很是多,我使用过的就有 wrk 、 ab 、 vegeta 、 siege 等。全部工具都支持对单个地址进行测试,部分工具支持经过地址列表进行批量测试。
除了 ab 这种历史比较悠久的工具,大部分现代压测工具效率都很是高,因此挑选哪一个区别不大。像我就是 wrk 的粉丝。
3. 记录关键信息
硬件配置对测试结果影响很是大。因此,在开始测试前,最好记录下你的服务器硬件状况,这包括 CPU、内存、网卡速度等等。若是有必要的话,那些关键的关联服务 - 好比数据库 - 的硬件配置也应该一并记录下来。
除了硬件配置外,还应该记录下与你的服务密切相关的其余配置信息,好比:
· 服务 Worker 类型是什么?线程、协程或是进程?开启了多少个?
· 是否使用数据库链接池
等等等等。当你对比多份测试结果时,这些配置信息就会派上用场。若是你还想分享测试结果给他人,那么提供这些配置信息是必须的。
进行压测
接下来就能够开始具体的压测过程了。通常来讲,针对单页面的压测过程都是很是简单的。你只须要提供少数几个参数:并发数、持续时间、页面地址,而后等待测试完成便可。以 wrk 为例:
$ wrk --latency -c100 -t5 -d 10 http://localhost:8080/hello/piglei
# -c 100:使用 100 个并发数
# -t 5:开启 5 个线程
# -d 10:持续 10 秒钟
一份完整的测试报告,一般要覆盖多个不一样的并发数配置,好比 [10, 100, 256, 512, 1024, 2048] 等等。你最终的测试结果,须要体现出服务在不一样并发数下的性能表现差别。
在压测过程当中,还有几个注意点:
1. 专机专用
执行测试工具的机器与测试目标服务所在的机器上,最好不要运行其余无关的程序。这样能够最大程度减少对测试结果的影响。
2. 测试时间不要太短
缓存须要预热,服务也须要一段时间来稳定下来。因此,测试时间不要过短,好比小于 30 秒钟。太短的测试时间会影响结果的可靠性。
为了让测试结果更可靠,请让每次测试时间至少超过一分钟,好比 3-5 分钟。
3. 不要让测试机成为瓶颈
如今的服务器配置愈来愈强大,颇有可能,你的目标服务处理能力还没达到瓶颈。你的测试机就已经先不行了。因此,在测试过程当中,请一并关注你的测试机负载状况。
若是发现由于测试机自身瓶颈致使测试结果不许确,请使用更好的机器,或尝试同时使用多台测试机。
4. 调整好系统参数
在开始压测前,确保系统的最大文件描述符数量等参数已经被调优过,避免影响压测过程。
查看压测结果
如下是执行 wrk 后的输出结果:
Running 10s test @ http://localhost:8080/hello/piglei 5 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 336.28ms 651.93ms 1.72s 81.42% Req/Sec 657.74 547.89 3.47k 72.81% Latency Distribution 50% 28.88ms 75% 38.64ms 90% 1.71s 99% 1.72s 33320 requests in 10.00s, 4.10MB read Requests/sec: 3331.92 Transfer/sec: 419.74KB |
在一次压测结果中,有不少有用的指标:
· 吞吐率 Requests/sec: 服务吞吐能力,也就是一秒钟平均处理多少请求数。它一般是压测结果中最重要的指标。
· 数据传输速率 Transfer/sec: 数据传输速率,压测响应结果较大的页面时,请尤为注意该值有没有达到网络瓶颈。
· 响应时间 Latency: 有关响应时间有不少不一样值,请不要只关注平均响应时间,更须要注意最小值、最大值、百分位值、标准差等等。
· 错误请求数: 当并发数太高,或服务处理能力不够时。请求就能够发生错误。你的服务能够最多承受多少并发而不产生错误?这是须要重点关注的指标之一。
可能影响压测结果的因素
1. HTTP 响应是否开启 Gzip 压缩
若是目标服务处在 Nginx 等支持 gzip 压缩的服务后,而恰好请求响应体又比较大。那么是否开启压缩会较大程度影响到压测结果。每一个工具开启压缩的方式都不同,通常状况下,你须要手动添加 Accept-Encoding: gzip, defalte 请求头来开启 Gzip 压缩。
2. 测试机器与目标服务之间的网络质量
测试机器和目标服务之间的网络情况会很大程度影响压测结果。因此,最好保证测试机与目标服务处在同一网段。同时关注压测结果中的数据传输速度(Transfer/sec)是否接近网络速率极限值。
3. 负载均衡器
若是你的目标服务前面有配置负载均衡器,那么它可能会对测试结果产生影响。
好比,使用 Nginx 的 proxy_pass 配置的后端服务,极限 RPS 在几千左右。若是后端服务的吞吐率很是高,那就须要考虑负载均衡器会不会成为你测试的瓶颈所在。
4. 是否开启了 HTTP 长链接
较现代的 HTTP 服务器基本都支持持久化链接(之前俗称 keep-alive),在测试过程当中,请肯定你的测试工具与服务端是否都开启了 HTTP 长链接选项。
由于每次压测一般要产生很是屡次请求,客户端的链接是否能够复用对结果影响很是大。能够的话,请将开启或关闭长链接做为两种状况分开测试。