美文网首页性能测试分析Locust
Locust性能测试实施细节

Locust性能测试实施细节

作者: 阿羅 | 来源:发表于2017-04-09 14:34 被阅读4659次

    引言

    当我们做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式的指引,对于一些实施的细节信息还比较欠缺,本文根据作者的实际应用经验,列举了部分使用细节,希望能为需要的朋友提供一点有用的信息。

    相关文章

      网友评论

        本文标题:Locust性能测试实施细节

        本文链接:https://www.haomeiwen.com/subject/ukpigttx.html