locustio
什么是 locustio?
Locust 是易于使用, 分布式的用户负载测试工具. 用于网站 (或其他系统) 的负载测试, 计算出系统可以处理并发用户数.
测试时大量蝗虫会攻击你的网站. 每只蝗虫 (或叫测试用户) 可以自定义, 测试过程由 web 界面实时监控. 这能帮助测试并确定瓶颈.
Locust 完全基于的事件, 单机可以支持数千用户. 它不使用回调, 而是基于轻量进程 gevent, 能简单地实线各种场景.
image.png
特点
Python 书写场景
无需笨重的 UI 或 XML. 仅仅是代码, 协程而不是回调.
分布式, 可扩展和, 支持成千上万的用户
基于 Web 的用户界面
Locust 有整洁 html + JS 用户界面, 实时展示测试细节, 跨平台和易于扩展.
可以测试任何系统
可控制
事件完全由 gevent 处理.
背景
我们研究了现有的解决方案, 都不符合要求. 比如 Apache JMeter 和 Tsung.JMeter 基于 UI 操作, 容易上手, 但基本上不具备编程能力. 其次 JMeter 基于线程, 要模拟数千用户几乎不可能. Tsung 基于 Erlang, 能模拟上千用户并易于扩展, 但它它基于 XML 的 DSL, 描述场景能力弱, 且需要大量的数据处理才知道测试结果.
无论如何, 我们试图解决创建 Locust, 当这些问题. 希望以上都不是 painpoints 应该存在.
我想你可以说我们真的只是想在这里从头开始自己的痒. 我们希望其他人会发现, 因为我们做的是有益的.
作者
Jonatan Heyman (@jonatanheyman on Twitter)
Carl Byström (@cgbystrom on Twitter)
Joakim Hamrén (@Jahaaja on Twitter)
- Hugo Heyman (@hugoheyman on Twitter)
- License: MIT
安装
安装:"pip install locustio" 或者 "easy_install locustio"
检验:
执行 "locust --help" 能看到如下信息表示安装成功:
- # locust --help
- Usage: locust [options] [LocustClass [LocustClass2 ... ]]
- Options:
- -h, --help show this help message and exit
- -H HOST, --host=HOST Host to load test in the following format:
- http://10.21.32.33
- --web-host=WEB_HOST Host to bind the web interface to. Defaults to '' (all
- interfaces)
- -P PORT, --port=PORT, --web-port=PORT
- Port on which to run web host
- -f LOCUSTFILE, --locustfile=LOCUSTFILE
- Python module file to import, e.g. '../other.py'.
- ...
主要需要 Python 2.6+, 不支持 python3. 分布式测试还需要安装 pyzmq. 尽管 locustio 可以在 Windows 运行, 但是考虑效率不推荐
快速入门
编写脚本
- #!/usr/bin/env python
- # coding=utf-8"""
- Locust quickstart!
- Copyright 2015.05.08 Rongzhong.Xu xurongzhong#126.com
- http://automationtesting.sinaapp.com
- """from locust import HttpLocust, TaskSet, taskclass UserBehavior(TaskSet):
- """
- Locust test class
- """ def on_start(self):
- """called when a Locust start before any task is scheduled""" self.login()
- def login(self):
- "pass" pass
- @task(2)
- def index(self):
- "http://automationtesting.sinaapp.com/" self.client.get("/")
- @task(1)
- def about(self):
- "http://automationtesting.sinaapp.com/about" self.client.get("/about")class WebsiteUser(HttpLocust):
- """
- The HttpLocust class inherits from the Locust class, and it adds
- a client attribute which is an instance of HttpSession,
- that can be used to make HTTP requests.
- """ task_set = UserBehavior
- min_wait = 5000 max_wait = 9000
HttpLocust 继承自 Locust, 添加了 client 属性. client 属性是 HttpSession 实例, 可以用于生成 HTTP 请求.
on_start 为 client 初始化时执行的步骤.
task 表示下面方法是测试内容, 里面的数字执行比例, 这里 about 页面占三分之一, 主页占三分之二.
task_set 指定 client 执行的类. min_wait 和 max_wait 为两次执行之间的最小和最长等待时间.
启动
启动 locust 后台
# locust --host=http://automationtesting.sinaapp.com[2015-05-08 16:33:49,166] andrew-Hi-Fi-A88S2/INFO/locust.main: Starting web monitor at *:8089[2015-05-08 16:33:49,167] andrew-Hi-Fi-A88S2/INFO/locust.main: Starting Locust 0.7.2
在浏览器启动 locust
打开 http://127.0.0.1:8089/ , 配置模拟的用户数 "Number of users to simulate" 和每秒发起的用户数 "Hatch rate", 提交执行测试.
这时在浏览器就可以看到实时的测试结果. 点击浏览器上方的 "stop" 即可停止测试.
查看报告:
命令行按 Ctrl + c , 可以显示一些摘要
- # locust --host=http://automationtesting.sinaapp.com
- [2015-05-08 16:33:49,166] andrew-Hi-Fi-A88S2/INFO/locust.main: Starting web monitor at *:8089[2015-05-08 16:33:49,167] andrew-Hi-Fi-A88S2/INFO/locust.main: Starting Locust 0.7.2[2015-05-08 16:42:18,656] andrew-Hi-Fi-A88S2/INFO/locust.runners: Hatching and swarming 8 clients at the rate 2 clients/s...
- [2015-05-08 16:42:22,663] andrew-Hi-Fi-A88S2/INFO/locust.runners: All locusts hatched: WebsiteUser: 8[2015-05-08 16:42:22,663] andrew-Hi-Fi-A88S2/INFO/locust.runners: Resetting stats
- ^C[2015-05-08 16:48:19,884] andrew-Hi-Fi-A88S2/ERROR/stderr: KeyboardInterrupt
- [2015-05-08 16:48:19,884] andrew-Hi-Fi-A88S2/INFO/locust.main: Shutting down (exit code 0), bye.
- Name # reqs # fails Avg Min Max | Median req/s
- --------------------------------------------------------------------------------------------------------------------------------------------
- GET / 36 0(0.00%) 260 206 411 | 250 0.90 GET /about 17 0(0.00%) 199 146 519 | 170 0.10--------------------------------------------------------------------------------------------------------------------------------------------
- Total 53 0(0.00%) 1.00Percentage of the requests completed within given times
- Name # reqs 50% 66% 75% 80% 90% 95% 98% 99% 100%--------------------------------------------------------------------------------------------------------------------------------------------
- GET / 36 250 260 260 270 370 400 410 410 411 GET /about 17 170 180 180 200 290 520 520 520 519--------------------------------------------------------------------------------------------------------------------------------------------
网页上可以下载 csv 文件, 一个是调配记录, 一个是请求记录.
# cat distribution_1431074713.45.csv "Name","# requests","50%","66%","75%","80%","90%","95%","98%","99%","100%""GET /",36,250,260,260,270,370,400,410,410,411"GET /about",17,170,180,180,200,290,520,520,520,519"None Total",53,250,250,260,260,310,400,410,520,519# cat requests_1431074710.05.csv"Method","Name","# requests","# failures","Median response time","Average response time","Min response time","Max response time","Average Content Size","Requests/s""GET","/",36,0,250,260,206,411,9055,0.76"GET","/about",17,0,170,199,146,519,4456,0.36"None","Total",53,0,250,241,146,519,7579,1.12
其他:
指定测试文件启动: locust -f ../locust_files/my_locust_file.py --host= http://example.com/
分布式测试时作为主测试机: locust -f ../locust_files/my_locust_file.py --master --host= http://example.com/
分布式测试时作为从测试机: locust -f ../locust_files/my_locust_file.py --slave --master-host=192.168.0.100 --host=http://example.com.master-host 的默认值是 127.0.0.1 http://example.com.xn--master-host127-l73wy28wz9vcjq8dxiwd.0.0.1/ .
locustfile
locustfile 需要定义至少一个 locust 类.
Locust 类
locust 类代表用户. 属性如下:
task_set 属性
task_set 属性指向定义了用户的行为的 TaskSet 类.
min_wait 和 max_wait 属性
两次执行之间的最小和最长等待时间, 单位: 毫秒, 即执行各任务之间等待时间. 默认为 1000, 并且因此蝗虫永远等待 1 秒各任务之间如果 min_wait 和 MAX_WAIT 未声明.
用下面 locustfile, 每个用户将等待任务之间 5 到 15 秒:
weight 属性
可以同时执行同一文件的多个 locust:
# locust -f locust_file.py WebUserLocust MobileUserLocust
weight 标识执行比例, 这里 WebUserLocust 的执行次数 3 倍于 MobileUserLocust:
- class WebUserLocust(Locust):
- weight = 3
- ....class MobileUserLocust(Locust):
- weight = 1
- ....
host 属性
URL 的前缀(如 "http://automationtesting.sinaapp.com/"). 通常在命令行使用 --host 选项指定. 也可以设置 host 属性, 在命令行没有指定时作为默认值.
TaskSet 类
TaskSet 表示任务的集合. 任务可以嵌套, 比如:
- Main user behaviour
- Watch movie
- Filter movies
- Read thread
- New thread
- View next page
- Reply
- Index page
- Forum page
- Browse categories
- About page
嵌套的 python 代码示例:
- class ForumPage(TaskSet): @task(20)
- def read_thread(self): pass @task(1)
- def new_thread(self): pass @task(5)
- def stop(self): self.interrupt()class UserBehaviour(TaskSet): tasks = {ForumPage:10}
- @task
- def index(self): pass</pre>
类嵌套示例:
- class MyTaskSet(TaskSet): @task
- class SubTaskSet(TaskSet): @task
- def my_task(self): pass</pre>
HTTP 请求
HttpLocust 继承自 Locust, 添加了 client 属性. client 属性是 HttpSession 实例, 调用了 requests, 可以用于生成 HTTP 请求. self.client 设置了属性指向 self.locust.client.
get 和 post 示例:
# getresponse = self.client.get("/about")print "Response status code:", response.status_codeprint "Response content:", response.content# postresponse = self.client.post("/login", {"username":"testuser", "password":"secret"})</pre>
注意失败的任何请求如连接错误, 超时等不产生异常, 而是返回 None,status_code 是 0.
默认只要返回的不是 2 都是失败. 也可以设置失败和成功:
- with client.get("/", catch_response=True) as response:
- if response.content != "Success":
- response.failure("Got wrong response")with client.get("/does_not_exist/", catch_response=True) as response:
- if response.status_code == 404:
- response.success()</pre>
动态参数:
- # Statistics for these requests will be grouped under: /blog/?id=[id]for i in range(10):
- client.get("/blog?id=%i" % i, name="/blog?id=[id]")</pre>
来源: http://www.jianshu.com/p/12bfee03f273