Locust部署与使用(MacOS)

本文介绍Locust性能测试框架的基本概念、部署步骤、使用方法及运行模式。涵盖参数化、关联与检查点设置等高级技巧,并详细解释了单进程与多进程分布式运行的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、  Locust前言

在Locust测试框架中,测试场景是采用纯Python脚本进行描述的。对于最常见的HTTP(S)协议的系统,Locust采用Python的requests库作为客户端,使得脚本编写大大简化,富有表现力的同时且极具美感。而对于其它协议类型的系统,Locust也提供了接口,只要我们能采用Python编写对应的请求客户端,就能方便地采用Locust实现压力测试。从这个角度来说,Locust可以用于压测任意类型的系统。

在模拟有效并发方面,Locust的优势在于其放弃了进程和线程,完全基于事件驱动,使用gevent提供的非阻塞IOcoroutine来实现网络层的并发请求,因此即使是单台压力机也能产生数千并发请求数;再加上对分布式运行的支持,理论上来说,Locust能在使用较少压力机的前提下支持极高并发数的测试。

二、  Locust部署

1、安装Python

官方:https://www.python.org/

Linux 升级 Python 至 3.x参照如下文章

http://blog.youkuaiyun.com/liang19890820/article/details/51079633

 

2、安装pip

sudo easy_install pip

 

3、 安装Homebrew  

参照网址:https://brew.sh/

 

4、 安装依赖包libev

brew install libev

 

5、 安装 pyzmq

如果你打算运行Locust 分布在多个进程/机器,我们建议你也安装pyzmq.

pip install pyzmq

 

6、安装locustio

pip install locustio


验证是否安装成功

 locust--help


 

三、  Locust使用

1、 参数化

1)循环取数据,数据可重复使用

所有并发虚拟用户共享同一份测试数据,各虚拟用户在数据列表中循环取值。

例如,模拟5用户并发请求网页,总共有100个URL地址,每个虚拟用户都会依次循环加载这100个URL地址;加载示例如下表所示。

代码示例;

from locust import TaskSet, task, HttpLocust
#循环取数据,数据可重复使用
class UserBehavior(TaskSet):
    def on_start(self):
        self.index = 0
        pass
    @task
    def test_visit(self):
        data = self.locust.share_data[self.index]
        self.index = (self.index + 1) % len(self.locust.share_data)
        print('数据 user_id: {}, order_id: {}' \
              .format(data['user_id'], data['order_id']))
        payload = {
            'user_id': data['user_id'],
            'order_id': data['order_id'],
            'channel': "beike",
            'type': "credit"
        }

        self.client.post('/risk/applyInfo', data=payload)
class WebsiteUser(HttpLocust):
    host = 'http://10.106.124.81:8080'
    task_set = UserBehavior
    share_data = []
    user_id = 40000000001
    order_id = 450000001
    for index in range(0, 100):
        data = {
            "user_id": "%d" % user_id,
            "order_id": "%d" % order_id,
        }
        user_id += 1
        share_data.append(data)
    min_wait = 1000
    max_wait = 1000

 

2)保证并发测试数据唯一性,不循环取数据

所有并发虚拟用户共享同一份测试数据,并且保证虚拟用户使用的数据不重复。

例如模拟5用户并发请求网页,总共有100个URL地址,要求每个请求地址不重复,直到100个URL请求完毕后结束;加载示例如下表所示。




代码示例;

t            data = self.locust.user_data_queue.get()
        except queue.Empty:
            print('运行用户已跑完')
            exit(0)
        print('数据 user_id: {}, order_id: {}'\
              .format(data['user_id'], data['order_id']))
        payload = {
            'user_id': data['user_id'],
            'order_id': data['order_id'],
            'channel': "beike",
            'type': "credit"
        }
        self.client.post('/risk/applyInfo', data=payload)
class WebsiteUser(HttpLocust):
    host = 'http://10.106.124.81:8080'
    task_set = UserDatasource
    user_data_queue = queue.Queue()

    user_id = 40000000001
    order_id = 450000001
    for index in range(0,100):
        data = {
            "user_id": "%d" % user_id,
            "order_id": "%d" % order_id,
        }
        user_id += 1
        order_id += 1
        user_data_queue.put_nowait(data)
    min_wait = 1000
    max_wait = 1000

 

 

3)保证并发测试数据唯一性,可循环取数据

所有并发虚拟用户共享同一份测试数据,并且保证虚拟用户使用的数据不重复。

例如模拟5用户并发请求网页,总共有100个URL地址,要求每个请求地址不重复,但是可循环使用数据;加载示例如下表所示。


代码示例;

from locust import TaskSet, task, HttpLocust
import queue
#保证并发测试数据唯一性,循环取数据
#该种场景的实现方式与上一种场景基本相同,唯一的差异在于,每次使用完数据后,需要再将数据放入队列中
# http://10.106.124.81:8080/risk/applyInfo?user_id=40000050001&channel=beike&order_id=450050001&type=credit
class UserDatasource(TaskSet):
    @task
    def test_applyInfo(self):
        try:
            data = self.locust.user_data_queue.get()
        except queue.Empty:
            print('运行用户已跑完')
            exit(0)
        print('数据 user_id: {}, order_id: {}'\
              .format(data['user_id'], data['order_id']))
        payload = {
            'user_id': data['user_id'],
            'order_id': data['order_id'],
            'channel': "beike",
            'type': "credit"
        }
        self.client.post('/risk/applyInfo', data=payload)
        self.locust.user_data_queue.put_nowait(data)
class WebsiteUser(HttpLocust):
    host = 'http://10.106.124.81:8080'
    task_set = UserDatasource
    user_data_queue = queue.Queue()

    user_id = 40000000001
    order_id = 450000001
    for index in range(0,50):
        data = {
            "user_id": "%d" % user_id,
            "order_id": "%d" % order_id,
        }
        user_id += 1
        order_id += 1
        user_data_queue.put_nowait(data)
    min_wait = 1000
    max_wait = 1000

 

 

1、关联与检查点

代码示例

from locust import HttpLocust, TaskSet, task
import re
class WebsiteTasks(TaskSet):
    def on_start(self):
        userinfo = {
                'nickname': '15811539615',
                'password': '4297F44B13955235245B2497399D7A93',
                'loanCommentCode': ""
            }
        with self.client.post("login/userlogin.shtml", catch_response=True,verify=False,data=userinfo) as response:
            html = response.text
            url = response.url
            print('url前缀%s' % url)
            self.validatelogin(html, response)

    @staticmethod
    #验证登录成功
    def validatelogin(html, response):
        result = re.search('message":".*?(\w+).*?","success', html)
        print('响应字符串:%s' % html)
        print('检查返回比对的字符串:%s'%result.group(1))
        if result.group(1) == '登陆成功':
            print('登录验证成功!')
        else:
            print('登录失败!')
            response.failure('登录失败')

    @staticmethod
    #验证我的账户跳转成功
    def validateaccount(html, response):
        result = re.search('class="text-info">.*?(\w+).*?</a><i class', html)
        # print('响应字符串:%s' % html)
        print('检查返回比对的字符串:%s' % result.group(1))
        if result.group(1) == 'lc303038910':
            print('我的账户跳转成功!')
        else:
            print('我的账户跳转失败!')
            response.failure('我的账户跳转失败')

    @task
    def useraccount(self):
        with self.client.post("usercenter/accountcenter.shtml", catch_response=True,verify=False) as response:
            html = response.text
            url = response.url
            print('url前缀%s' % url)
            self.validateaccount(html,response)

class WebsiteUser(HttpLocust):
    task_set = WebsiteTasks
    host = "https://www.caifuxq.com/"
    min_wait = 1000
    max_wait = 1000

 

四、  Locust运行模式

在开始运行Locust脚本之前,我们先来看下Locust支持的运行模式。

运行Locust时,通常会使用到两种运行模式:单进程运行和多进程分布式运行。

单进程运行模式的意思是,Locust所有的虚拟并发用户均运行在单个Python进程中,具体从使用形式上,又分为no_web和web两种形式。该种模式由于单进程的原因,并不能完全发挥压力机所有处理器的能力,因此主要用于调试脚本和小并发压测的情况

当并发压力要求较高时,就需要用到Locust的多进程分布式运行模式。从字面意思上看,大家可能第一反应就是多台压力机同时运行,每台压力机分担负载一部分的压力生成。的确,Locust支持任意多台压力机(一主多从)的分布式运行模式,但这里说到的多进程分布式运行模式还有另外一种情况,就是在同一台压力机上开启多个slave的情况。这是因为当前阶段大多数计算机的CPU都是多处理器(multipleprocessor cores),单进程运行模式下只能用到一个处理器的能力,而通过在一台压力机上运行多个slave,就能调用多个处理器的能力了。比较好的做法是,如果一台压力机有N个处理器内核,那么就在这台压力机上启动一个masterNslave。当然,我们也可以启动N的倍数个slave,但是根据我的试验数据,效果跟N个差不多,因此只需要启动N个slave即可。

1、 单进程运行

no_web(表示不使用web界面)

Locust是通过在Terminal中执行命令进行启动的,通用的参数有如下两个:

-H, --host:被测系统的host,若在Terminal中不进行指定,就需要在Locust子类中通过host参数进行指定;

-f, --locustfile:指定执行的Locust脚本文件;

如果采用no_web形式,则需使用--no-web参数,并会用到如下几个参数。

-c, --clients:指定并发用户数;

-n, --num-request:指定总执行测试;

-r, --hatch-rate:指定并发加压速率,默认值位1。

-t, 设置设置运行时间

终端命令



web

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

-P, --port:指定web端口,默认为8089.


此时,Locust并没有开始执行测试,还需要在Web页面中配置参数后进行启动。

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

在Locust的Web管理页面中,需要配置的参数只有两个:

Number of users to simulate: 设置并发用户数,对应中no_web模式的-c,--clients参数;

Hatch rate (users spawned/second): 启动虚拟用户的速率,对应着no_web模式的-r,--hatch-rate参数。

--no-reset-stats   就能统计全部数据了

参数配置完毕后,点击【Startswarming】即可开始测试。

 

1、 多进程分布式运行

不管是单机多进程,还是多机负载模式,运行方式都是一样的,都是先运行一个master,再启动多个slave。启动master时,需要使用--master参数;同样的,如果要使用8089以外的端口,还需要使用-P,--port参数。

locust -f test4.py --no-reset-stats--master


master启动后,还需要启动slave才能执行测试任务。

启动slave时需要使用--slave参数;在slave中,就不需要再指定端口了。

locust -f test4.py --no-reset-stats --slave


如果slave与master不在同一台机器上,还需要通过--master-host参数再指定master的IP地址。

locust -f test4.py --no-reset-stats --slave--master-host=10.106.29.235



五、Locust场景控制

1、设置并发数

通过代码中min_wait max_wait设置请求之间的间隔时间

两个值设置一样代表请求之间的间隔时间固定

以下以无界面方式运行脚本c

locust -ftest4.py --no-web -c 2 -n 10

例min_wait max_wait分别设置1(间隔1s)   -c设置2   -n设置10

场景:每秒并发2  共执行10条记录



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值