一、架构与核心类
基本介绍
Locust是开源、使用Python开发、基于事件、支持分布式并且提供Web UI进行测试执行和结果展示的性能测试工具。
Locust的主要特性有两个:
- 模拟用户操作:支持多协议,Locust可以用于压测任意协议类型的系统
- 并发机制:摒弃了进程和线程,采用协程(gevent)的机制,单台测试机可以产生数千并发压力
Locust使用了以下几个核心库:
1) gevent
gevent是一种基于协程的Python网络库,它用到Greenlet提供的,封装了libevent事件循环的高层同步API。
2) flask
Python编写的轻量级Web应用框架。
3) requests
Python Http库
4) msgpack-python
MessagePack是一种快速、紧凑的二进制序列化格式,适用于类似JSON的数据格式。msgpack-python主要提供MessagePack数据序列化及反序列化的方法。
5) pyzmq
pyzmq是zeromq(一种通信队列)的Python实现,主要用来实现Locust的分布式模式运行
系统架构及对比
我们知道,完整的压测系统应该包含以下组件:
相比于主流的压测系统LoadRunner和Jmeter,Locust是一个更为纯粹的开源压测系统,框架本身的结构并不复杂,甚至只提供了最基础的组件,但也正因为如此,Locust具有极高的可编程性和扩展性。对于测试开发同学来说,可以比较轻松地使用Locust实现对任意协议的压测。
工具简单对比
LoadRunner | Jmeter | Locust | |
---|---|---|---|
压力生成器 | √ | √ | √ |
负载控制器 | √ | √ | √ |
系统资源监控器 | √ | x | x |
结果采集器 | √ | √ | √ |
结果分析器 | √ | √ | √ |
上表简单展示了几个工具包含的压测组件,Locust的架构非常简单,部分组件的实现甚至都不完善,比如结果分析器,Locust本身并没有很详细的测试报告。但这并不妨碍它成为优秀的开源框架。
Locust的架构
Locust 最近发布了1.x 版本,代码进行了重构,重封装,对很多类进行了重命名,本文尽量使用新名词,但涉及的旧名词不影响理解。
- locust架构上使用master-slave模型,支持单机和分布式
- master和slave(即worker)使用 ZeroMQ 协议通讯
- 提供web页面管理master,从而控制slave,同时展示压测过程和汇总结果
- 可选no-web模式(一般用于调试)
- 基于Python本身已经支持跨平台
为了减少CPython的GIL限制,充分利用多核CPU,建议单机启动CPU核数的slave(多进程)。
核心类
上面展示的Locust架构,从代码层面来看究竟是如何实现的呢?下面我们就来窥视一
简单来说,Locust的代码分为以下模块:
- Runner-执行器,Locust的核心类,定义了整个框架的执行逻辑,实现了Master、Slave(worker)等执行器
- User-压测用例,提供了HttpUser压测http协议,用户可以定义事务,断言等,也可以实现特定协议的User
- Socket-通信器,提供了分布式模式下master和slave的交互方式
- RequestStats-采集、分析器,定义了结果分析和数据上报格式
- EventHook-事件钩子,通过预先定义的事件使得我们可以在这些事件发生时(比如slave上报)做一些额外的操作
- WebUI-提供web界面的操作台和压测过程展示
下面我们看看核心类的主要成员变量和方法
- 用户定义的User类作为Runner的user_classes传入
- master的client_listener监听施压端client消息
- slave的worker方法监听master消息
- slave的stats_reporter方法上报压测数据,默认3s上报一次
- slave的start启动协程,使用master分配的并发数开始压测
- slave默认1s上报一次心跳,如果master超过3s未收到某个slave的心跳则会将其标记为missing状态
- TaskSet和User持有client,可以在类中直接发起客户端请求,client可以自己实现,Locust只实现了HttpUser
二、Runner的状态与通信机制
接下来我们继续了解Locust分布式压测的核心:Runner的状态和通信机制。我们知道Locust等压测工具支持分布式压测,就是说理论上可以通过不断添加压力机(worker)提高并发数量,这个机制让使用者可以自由地增减机器资源,从而达到期望的施压能力。
Runner状态机
在分布式场景下,除了数据一致性,状态同步也是非常重要的。在Locust的master-slave架构下,需要管理master和slave的状态,不仅为了控制压测的开始