Locust使用教程

Locust 使用教程

About

前言

What is Coroutine?

协程又称为微线程,纤程。英文名Coroutine:协程是一种用户态的轻量级线程
协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复之前保存的寄存器上下文和栈

 # 优点:
1. 无需线程上下文切换的开销
2. 无需原子操作(不会被线程调度机制打断的操作)锁定以及同步的开销
3. 高并发+高扩展性+低成本

 # 缺点:
1. 无法利用多核资源:协程的本质是单线程,需要和进程配合才能运行在多CPU上
2. 进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序

What is Gevent?

gevent是一个基于协程的Python网络库,它使用greenlet在libev或libuv事件循环之上提供一个高级的同步API

# libev是一个高性能的事件循环库

What is Python GIL?
GIL 全局解释器锁  (global interrupter lock)
# 由来:
1. 解决多线程之间数据完整性和状态同步的最简单方法自然就是加锁

# 引发的问题:
1. 任何进程中,同一时刻只能有一个线程在执行 (多cup的资源,只有1个cpu在使用,其它处于空闲状态)

# 应对方案:
多开进程去实现多线程任务

GIL并非是Python的特性,而是Python 解释器CPython解释器的特性

Python解释器有如下几类

image

# CPython:
官方默认版本,使用C语言开发,是Python使用最广泛的解释器,有GIL.
# IPython: 
IPython是基于CPython之上的交互式解释器,其它方面和CPython相同.
# PyPy: 
PyPy采用JIT(Just In Time)也就是即时编译编译器,对Python代码执行动态编译,目的是加快执行速度,有GIL.
# Jython: 
运行在Java平台上的解释器,把Python代码编译为Java字节码执行,没有GIL.
# IronPython:
IronPython和Jython类似,只不过IronPython是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码,没有GIL.

What is Locust?

一个易于使用的分布式用户负载测试工具。它旨在对网站(或其他系统)进行负载测试,并确定一个系统可以处理多少并发用户。

Locust是完全基于事件的,因此可以在单台机器中支持数以千计的用户在线。和其它基于事件的程序相比较,它是不需要使用回调的。相反,它通过gevent使用轻量级的进程。每一个locust测试你的网站时,实际上是真实的在内部运行它自己的进程(或greenlet,准确的说)。这样就允许你不使用复杂的回调方法,而是使用Python编写复杂的场景。

image

# gevent
在Python中实现协程的第三方库。协程又叫微线程Corouine。使用gevent可以获取极高的并发能力;

# flask
轻量级的web开发框架,和django相当;

#requests
支持http/https访问的库;

# msgpack-python
一种快速、紧凑的二进制序列化格式,使用与类似json的数据;

# six
提供了一些简单的工具封装Python2和Python3 之间的差异;

# pyzmq
支撑 Locust运行在多个进程或多个机器(分布式)
....

Locust 核心类介绍
  • TaskSet()

定义了每个用户的任务集合,测试任务开始后,每个Locust用户会从TaskSet中随机挑选(如果定义了任务间的权重关系,那么就是按照权重关系随机挑选)一个任务执行,然后随机等待Locust类中定义的min_wait和max_wait(如果TaskSet类中也定义了min_wait或者max_wait,按照TaskSet中的为准)之间的一段时间,执行下一个任务。

# TaskSet 提供的常用方法
client # client  源码:return self.locust.client  返回 locust的client,用法与Request库类似
locust # 当任务集被实例化时,将引用根蝗虫类实例
parent # 任务集被实例化时,指向每个TaskSet所属的父类TaskSet (用于 TaskSet嵌套)
client # 指向TaskSet所属的父HttpLocust类的client属性,self.client与self.locust.client效果是一样的。如果TaskSet所属的父类是个Locust类,则没有这个client属性

  • HttpLocust()

继承了Locust类,表示将要生成的每一个虚拟的HTTP用户,用来发送请求到进行负载测试的系统

# HttpLocust 继承 Locust   -> class HttpLocust(Locust):

task_set # 定义locust执行任务行为的 任务集类   如:task_set = TestDemo
host  # 要测试的 目标服务地址
min_wait = 1000  # 单位为ms  最小等待时间  最新版本 已弃用 (当前版本:0.14.5)
max_wait = 1000  # 单位为ms  最大等待时间  最新版本 已弃用 (当前版本:0.14.5)
# between(min_wait, max_wait)
wait_time = between(100, 1000)  # 单位为ms   等待时间  任务执行间隔时间 随机从100~1000区间内取

  • taks 装饰器 可控制任务执行权重比,defautl:weight=1 如下:
class ForumPage(TaskSet):
    @task(100)
    def read_thread(self):
        pass
            
    @task(7)
    def create_thread(self):
        pass

Locust安装
  • pip install locust
  • pip list 版本查看或 locust -v
关键
Quick start
import json
import os

from locust import HttpLocust, TaskSet, task, between


class Demo(TaskSet):
    @task
    def test_get(self):
        self.client.get("http://www.baidu.com")

    @task
    def test_post(self):
        responses = self.client.post(url='url', headers='headers', data='body')
        # 对返回内容 进行断言
        if responses.status_code == 200:
            rst = json.loads(responses.text, strict=False)
            if rst['code'] == '00000':
                responses.success()  # Locust ResponseContextManager类提供的  Report the response as successful
            else:
                responses.failure('code:%s ErrorMsg:%s' % (rst['code'], rst['errorMsg']))
        else:
            responses.failure('status_code:%s' % responses.status_code)


class WebsiteUser(HttpLocust):
    task_set = Demo
    host = 'http://www.baidu.com'  # 目标服务地址
    # min_wait = 1000  # 单位为ms  最小等待时间  最新版本 已弃用 (当前版本:0.14.5)
    # max_wait = 1000  # 单位为ms  最大等待时间  最新版本 已弃用 (当前版本:0.14.5)

    # between(min_wait, max_wait)
    wait_time = between(2, 5)  # 单位为s   等待时间  任务执行间隔时间


# 以下 便于当前脚本 本地调试
# 启动 当前脚本
if __name__ == "__main__":
    cmd = 'locust -f locust_demo.py'
    os.system(cmd)


  • 启动

image

image

image

界面参数解读

  • Number of users to simulate 虚拟用户数 VU
  • users spawned/second 每秒启动的 VU 数
  • RPS 真实数据= RPS/2 (每秒发出的请求数)

分布式(Linux)
  • master 启动:
# test.py 要执行的 脚本
# --master 指定当前 运行 进程为 master  (单机上可 同时 运行 master/slave)
# -P 指定 master 进程 对外提供访问的 端口

locust -f test.py --master -P 8181
  • Slave 启动:
# test.py 要执行的 脚本
# --slave 指定当前运行的 进程为slave
# --master-host 指定 master服务的地址
# -P 指定 master 进程 对外提供访问的 端口
 locust -f test.py --slave --master-host=192.168.1.20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值