51Testing软件测试论坛

标题: 深入浅出开源性能测试工具 Locust (使用篇 2) [打印本页]

作者: 乐哈哈yoyo    时间: 2017-6-27 11:56
标题: 深入浅出开源性能测试工具 Locust (使用篇 2)
Locust运行模式在开始运行Locust脚本之前,我们先来看下Locust支持的运行模式。
运行Locust时,通常会使用到两种运行模式:单进程运行和多进程分布式运行。
单进程运行模式的意思是,Locust所有的虚拟并发用户均运行在单个Python进程中,具体从使用形式上,又分为no_web和web两种形式。该种模式由于单进程的原因,并不能完全发挥压力机所有处理器的能力,因此主要用于调试脚本和小并发压测的情况。
当并发压力要求较高时,就需要用到Locust的多进程分布式运行模式。从字面意思上看,大家可能第一反应就是多台压力机同时运行,每台压力机分担负载一部分的压力生成。的确,Locust支持任意多台压力机(一主多从)的分布式运行模式,但这里说到的多进程分布式运行模式还有另外一种情况,就是在同一台压力机上开启多个slave的情况。这是因为当前阶段大多数计算机的CPU都是多处理器(multiple processor cores),单进程运行模式下只能用到一个处理器的能力,而通过在一台压力机上运行多个slave,就能调用多个处理器的能力了。比较好的做法是,如果一台压力机有N个处理器内核,那么就在这台压力机上启动一个master,N个slave。当然,我们也可以启动N的倍数个slave,但是根据我的试验数据,效果跟N个差不多,因此只需要启动N个slave即可。
脚本调试Locust脚本编写完毕后,通常不会那么顺利,在正式开始性能测试之前还需要先调试运行下。
不过,Locust脚本虽然为Python脚本,但却很难直接当做Python脚本运行起来,为什么呢?这主要还是因为Locust脚本中引用了HttpLocust和TaskSet这两个类,如果要想直接对其进行调用测试,会发现编写启动脚本是一个比较困难的事情。因为这个原因,刚接触Locust的同学可能就会觉得Locust脚本不好调试。
但这个问题也能克服,那就是借助Locust的单进程no_web运行模式。
在Locust的单进程no_web运行模式中,我们可以通过--no-web参数,指定并发数(-c)和总执行次数(-n),直接在Terminal中执行脚本。
在此基础上,当我们想要调试Locust脚本时,就可以在脚本中需要调试的地方通过print打印日志,然后将并发数和总执行次数都指定为1,执行形式如下所示。
$ locust -f locustfile.py --no-web -c 1 -n 1通过这种方式,我们就能很方便地对Locust脚本进行调试了。
执行测试Locust脚本调试通过后,就算是完成了所有准备工作,可以开始进行压力测试了。
Locust是通过在Terminal中执行命令进行启动的,通用的参数有如下两个:
除了这两个通用的参数,我们还需要根据实际测试场景,选择不同的Locust运行模式,而模式的指定也是通过其它参数来进行控制的。
单进程运行no_web
  1. <p>如果采用<code>no_web</code>形式,则需使用<code>--no-web</code>参数,并会用到如下几个参数。</p>

  2. <ul>
  3. <li>
  4. <code>-c, --clients</code>:指定并发用户数;</li>
  5. <li>
  6. <code>-n, --num-request</code>:指定总执行测试;</li>
  7. <li>
  8. <code>-r, --hatch-rate</code>:指定并发加压速率,默认值位1。</li>
  9. </ul>
  10. <pre class="highlight shell"><code><span class="gp">$ </span>locust -H http://debugtalk.com -f demo.py --no-web -c1 -n2
  11. <span class="o">[</span>2017-02-21 21:27:26,522] Leos-MacBook-Air.local/INFO/locust.main: Starting Locust 0.8a2
  12. <span class="o">[</span>2017-02-21 21:27:26,523] Leos-MacBook-Air.local/INFO/locust.runners: Hatching and swarming 1 clients at the rate 1 clients/s...
  13. Name                                                          <span class="c"># reqs      # fails     Avg     Min     Max  |  Median   req/s</span>
  14. --------------------------------------------------------------------------------------------------------------------------------------
  15. --------------------------------------------------------------------------------------------------------------------------------------
  16. Total                                                              0     0<span class="o">(</span>0.00%<span class="o">)</span>                                       0.00

  17. <span class="o">[</span>2017-02-21 21:27:27,526] Leos-MacBook-Air.local/INFO/locust.runners: All locusts hatched: WebsiteUser: 1
  18. <span class="o">[</span>2017-02-21 21:27:27,527] Leos-MacBook-Air.local/INFO/locust.runners: Resetting stats

  19. Name                                                          <span class="c"># reqs      # fails     Avg     Min     Max  |  Median   req/s</span>
  20. --------------------------------------------------------------------------------------------------------------------------------------
  21. GET /about/                                                        0     0<span class="o">(</span>0.00%<span class="o">)</span>       0       0       0  |       0    0.00
  22. --------------------------------------------------------------------------------------------------------------------------------------
  23. Total                                                              0     0<span class="o">(</span>0.00%<span class="o">)</span>                                       0.00

  24. Name                                                          <span class="c"># reqs      # fails     Avg     Min     Max  |  Median   req/s</span>
  25. --------------------------------------------------------------------------------------------------------------------------------------
  26. GET /about/                                                        1     0<span class="o">(</span>0.00%<span class="o">)</span>      17      17      17  |      17    0.00
  27. --------------------------------------------------------------------------------------------------------------------------------------
  28. Total                                                              1     0<span class="o">(</span>0.00%<span class="o">)</span>                                       0.00

  29. <span class="o">[</span>2017-02-21 21:27:32,420] Leos-MacBook-Air.local/INFO/locust.runners: All locusts dead

  30. <span class="o">[</span>2017-02-21 21:27:32,421] Leos-MacBook-Air.local/INFO/locust.main: Shutting down <span class="o">(</span><span class="nb">exit </span>code 0<span class="o">)</span>, bye.
  31. Name                                                          <span class="c"># reqs      # fails     Avg     Min     Max  |  Median   req/s</span>
  32. --------------------------------------------------------------------------------------------------------------------------------------
  33. GET /                                                              1     0<span class="o">(</span>0.00%<span class="o">)</span>      20      20      20  |      20    0.00
  34. GET /about/                                                        1     0<span class="o">(</span>0.00%<span class="o">)</span>      17      17      17  |      17    0.00
  35. --------------------------------------------------------------------------------------------------------------------------------------
  36. Total                                                              2     0<span class="o">(</span>0.00%<span class="o">)</span>                                       0.00

  37. Percentage of the requests completed within given <span class="nb">times
  38. </span>Name                                                           <span class="c"># reqs    50%    66%    75%    80%    90%    95%    98%    99%   100%</span>
  39. --------------------------------------------------------------------------------------------------------------------------------------
  40. GET /                                                               1     20     20     20     20     20     20     20     20     20
  41. GET /about/                                                         1     17     17     17     17     17     17     17     17     17
  42. --------------------------------------------------------------------------------------------------------------------------------------
  43. </code></pre>
  44. <p><strong>web</strong></p>

  45. <p>如果采用<code>web</code>形式,,则通常情况下无需指定其它额外参数,<code>Locust</code>默认采用<code>8089</code>端口启动<code>web</code>;如果要使用其它端口,就可以使用如下参数进行指定。</p>

  46. <ul>
  47. <li>
  48. <code>-P, --port</code>:指定web端口,默认为<code>8089</code>.</li>
  49. </ul>
  50. <pre class="highlight shell"><code><span class="gp">$ </span>locust -H http://debugtalk.com -f demo.py
  51. <span class="o">[</span>2017-02-21 21:31:26,334] Leos-MacBook-Air.local/INFO/locust.main: Starting web monitor at <span class="k">*</span>:8089
  52. <span class="o">[</span>2017-02-21 21:31:26,334] Leos-MacBook-Air.local/INFO/locust.main: Starting Locust 0.8a2
  53. </code></pre>
  54. <p>此时,<code>Locust</code>并没有开始执行测试,还需要在Web页面中配置参数后进行启动。</p>

  55. <p>如果<code>Locust</code>运行在本机,在浏览器中访问<code>http://localhost:8089</code>即可进入<code>Locust</code>的Web管理页面;如果<code>Locust</code>运行在其它机器上,那么在浏览器中访问<code>http://locust_machine_ip:8089</code>即可。</p>

  56. <p>在<code>Locust</code>的Web管理页面中,需要配置的参数只有两个:</p>

  57. <ul>
  58. <li>
  59. <code>Number of users to simulate</code>: 设置并发用户数,对应中<code>no_web</code>模式的<code>-c, --clients</code>参数;</li>
  60. <li>
  61. <code>Hatch rate (users spawned/second)</code>: 启动虚拟用户的速率,对应着<code>no_web</code>模式的<code>-r, --hatch-rate</code>参数。</li></ul>
复制代码
参数配置完毕后,点击【Start swarming】即可开始测试。


作者: 乐哈哈yoyo    时间: 2017-6-27 11:56
多进程分布式运行
不管是单机多进程,还是多机负载模式,运行方式都是一样的,都是先运行一个master,再启动多个slave。
启动master时,需要使用--master参数;同样的,如果要使用8089以外的端口,还需要使用-P, --port参数。
  1. $ locust -H http://debugtalk.com -f demo.py --master --port=8088
  2. [2017-02-21 22:59:57,308] Leos-MacBook-Air.local/INFO/locust.main: Starting web monitor at *:8088
  3. [2017-02-21 22:59:57,310] Leos-MacBook-Air.local/INFO/locust.main: Starting Locust 0.8a2
  4. master启动后,还需要启动slave才能执行测试任务。
  5. 启动slave时需要使用--slave参数;在slave中,就不需要再指定端口了。
  6. $ locust -H http://debugtalk.com -f demo.py --slave
  7. [2017-02-21 23:07:58,696] Leos-MacBook-Air.local/INFO/locust.main: Starting Locust 0.8a2
  8. [2017-02-21 23:07:58,696] Leos-MacBook-Air.local/INFO/locust.runners: Client 'Leos-MacBook-Air.local_980ab0eec2bca517d03feb60c31d6a3a' reported as
  9. ready. Currently 2 clients ready to swarm.
  10. 如果slave与master不在同一台机器上,还需要通过--master-host参数再指定master的IP地址。
  11. $ locust -H http://debugtalk.com -f demo.py --slave --master-host=<locust_machine_ip>
  12. [2017-02-21 23:07:58,696] Leos-MacBook-Air.local/INFO/locust.main: Starting Locust 0.8a2
  13. [2017-02-21 23:07:58,696] Leos-MacBook-Air.local/INFO/locust.runners: Client 'Leos-MacBook-Air.local_980ab0eec2bca517d03feb60c31d6a3a' reported as
  14. ready. Currently 2 clients ready to swarm.
复制代码

master和slave都启动完毕后,就可以在浏览器中通过http://locust_machine_ip:8089进入Locust的Web管理页面了。使用方式跟单进程web形式完全相同,只是此时是通过多进程负载来生成并发压力,在web管理界面中也能看到实际的slave数量。
测试结果展示
Locust在执行测试的过程中,我们可以在web界面中实时地看到结果运行情况。
相比于LoadRunner,Locust的结果展示十分简单,主要就四个指标:并发数、RPS、响应时间、异常率。但对于大多数场景来说,这几个指标已经足够了。

在上图中,RPS和平均响应时间这两个指标显示的值都是根据最近2秒请求响应数据计算得到的统计值,我们也可以理解为瞬时值。
如果想看性能指标数据的走势,就可以在Charts栏查看。在这里,可以查看到RPS和平均响应时间在整个运行过程中的波动情况。这个功能之前在Locust中一直是缺失的,直到最近,这个坑才被我之前在阿里移动的同事(网络IDmyzhan)给填上了。当前该功能已经合并到Locust了,更新到最新版即可使用。

除了以上数据,Locust还提供了整个运行过程数据的百分比统计值,例如我们常用的90%响应时间、响应时间中位值,该数据可以通过Download response time distribution CSV获得,数据展示效果如下所示。

总结
通过前面对Locust全方位的讲解,相信大家对Locust的功能特性已经非常熟悉了,在实际项目中将Locust作为生产力工具应该也没啥问题了。
不过,任何一款工具都不是完美的,必定都会存在一些不足之处。但是好在Locust具有极强的可定制型,当我们遇到一些特有的需求时,可以在Locust上很方便地实现扩展。
还是前面提到的那位技术大牛(myzhan),他为了摆脱CPython的GIL和gevent的 monkey_patch(),将Locust的slave端采用golang进行了重写,采用goroutine取代了gevent。经过测试,相较于原生的Python实现,他的这套golang实现具有5~10倍以上的性能提升。当前,他已经将该实现开源,项目名称为myzhan/boomer,如果大家感兴趣,可以阅读他的博客文章进一步了解,《用 golang 来编写压测工具》。
如果我们也想在Locust的基础上进行二次开发,那要怎么开始呢?
毫无疑问,阅读Locust的项目源码是必不可少的第一步。可能对于很多人来说,阅读开源项目源码是一件十分困难的事情,不知道如何着手,在知乎上也看到好多关于如何阅读开源项目源码的提问。事实上,Locust项目的代码结构清晰,核心代码量也比较少,十分适合阅读学习。哪怕只是想体验下阅读开源项目源码,或者说想提升下自己的Python技能,Locust也是个不错的选择。
作者: 巴黎的灯光下    时间: 2017-6-27 13:00
pip install locustio==0.8a2要更新这个版本;更新了也没有charts,望楼主回复下;
作者: 乐哈哈yoyo    时间: 2017-6-27 13:01
巴黎的灯光下 发表于 2017-6-27 13:00
pip install locustio==0.8a2要更新这个版本;更新了也没有charts,望楼主回复下;



更好的方式是,直接从github项目源码进行安装。

  1. $ pip install git+git://github.com/locustio/locust.git@master#egg=locustio
复制代码







欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2