Locust性能测试实施细节

引言

当我们做Web系统性能测试方案时,压力模拟工具的选择通常是一个绕不开的环节。对于大部分互联网公司的业务规模和测试资源投入,JMeter这个老牌开源性能测试工具能够满足大部分测试需求,它也可能是世面上书籍、博客教程丰富程度仅次于LoadRunner的性能测试工具。然而当我们的场景需要模拟的并发用户数以千为单位时,使用JMeter的成本越来越大,甚至超出我们掌握的资源。此时,我们开始寻找更低成本的方案,而Locust,为这样的方案带来了一种可能。

简介

Locust是开源、使用Python开发、基于事件、支持分布式并且提供Web UI进行测试执行和结果展示的性能测试工具。而它之所以能够在资源占用方面明显优于JMeter,一个关键点在于两者模拟虚拟用户的方式不同,JMeter通过线程来作为虚拟用户,而Locust借助gevent库对协程的支持,以greenlet来实现对用户的模拟,相同配置下Locust能支持的并发用户数相比JMeter可以达到一个数量级的提升。
Locust使用Python代码定义测试场景,目前支持Python 2.7, 3.3, 3.4, 3.5, 和3.6。它自带一个Web UI,用于定义用户模型,发起测试,实时测试数据,错误统计等,在最新未正式发布的v0.8a2(当前最新发布版本v0.8a1),还提供QPS、评价响应时间等几个简单的图表。

Summary Report
Charts

本文不会介绍Locust最基础的部署、运行等Quick start式内容,这部分内容请直接参照官网Quick start或者搜索Locust入门的博客,本文主要介绍一些目前网络上还比较缺少的,真正要用Locust来做Web系统性能测试时通常需要用到的内容或者可能遇到的问题

v0.8a2<a id="a2"></a>

如前文所说,当前官方最新发布的版本为v0.8a1,还不包含图表特性,而在官方Github上已经在v0.8a2完成了图表特性的合并,想要提前体验可以直接从Github获取master分支的代码,覆盖`[PythonHome]\Lib\site-packages`中的locust目录即可。

指定Web host

在Linux系统多网卡情况下,Locust自动选择网卡时可能会遇到error: [Errno 97] Address family not supported by protocol错误,此时可以通过直接指定web host来解决问题,使用选项--web-host来指定可用的地址,例:

locust -f xxx.py --web-host=127.0.0.1
locust -f xxx.py --web-host=192.168.1.2
locust -f xxx.py --web-host=localhost

断言

当我们没有自定义断言时,测试请求结果的状态(success/fail)取决于Http请求是否有异常出现,而在对我们的Web系统实施性能测试时,当我们需要更准确的业务成功率数据时,就需要通过对响应状态码、Response body等数据进行校验来给出结果,此时,可以通过ResponseContextManager来实现。首先在场景代码的发起请求参数中通过catch_response=True来捕获响应数据,然后对响应数据进行校验,最后使用success()/failure()两个方法来标识请求结果的状态。例:

from locust import HttpLocust, TaskSet,task
class UserBehavior(TaskSet):
    @task(2)
    def foo(self):
        with self.client.get("/", catch_response=True) as response:
            if response.status_code == 200:
                response.success()
        @task(1)
         def bar(self):
                reqBody = '{"username":"ellen_key", "password":"education"}'
                with self.client.post("/login", reqBody, catch_response=True) as response: 
                        if response.content == "":
                                response.failure("No data")
class WebsiteUser(HttpLocust):
    task_set = UserBehavior
    host = "http://foo.bar.com"
    min_wait = 0
    max_wait = 0

Json解析

Json作为一种轻量级的数据交换格式,以及被如今的互联网系统广泛采用。上一节的示例中,我们使用content获取完整的响应内容,实际测试实施中,对于动态的响应结果,可能更多的采用校验关键字段的方式对于Json格式的响应数据,要获取特定字段的值,可以直接使用内置的Json解析实现,例:
对于如下的响应结果:

{
  'code':0,
  'data':[
        {
          'id':123
        }
  ]
}

可以通过如下方式获取其中的关键数据:

with self.client.post("/login", reqBody, catch_response=True) as response: 
    json_resp = response.json()
    code = json_resp["code"]
    data_len = len(json_resp["data"])
    id = json_resp["data"][0]["id"]

自定义标签

从简介的Summary report图中可以看到,Locust的结果展示中,请求的默认名称是url的path部分,而为了报告更直观,或者当同一个业务有动态的path(如/user/[userid]),需要聚合时,可以通过name参数来自定义标签实现,例:

with  self.client.get("/account/{accountID}", catch_response=True, name = "getAccount") as resp:

分布式运行

Locust的分布式运行,master和slave节点都需要有场景脚本,分别以如下命令启动:

  • master:locust -f locustfile.py --master --web-host=x.x.x.x
  • slave:locust -f locustfile.py --slave --master-host=x.x.x.x
    master节点将运行Locust的Web UI服务,不会承担任何施压任务(不会模拟虚拟用户)。
    如前面的简介,Locust模拟并发用户是使用协程,也因此对于多核CPU的服务器,为良好的利用多核能力,建议一台slave服务器运行与CPU核数相当的slave

总结

Locust作为一个年轻的、轻量级的性能测试工具,网络上相关的应用文献特别是中文文献相对较少,而且多数是Quick start式的指引,对于一些实施的细节信息还比较欠缺,本文根据作者的实际应用经验,列举了部分使用细节,希望能为需要的朋友提供一点有用的信息。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容