使用Locust框架进行压力测试

Locust是一种基于python语言的压测框架,本质上是基于gevent的多协程机制。这里协程跟线程(thread)的区别是切换开销小、可以由用户控制切换。但是一个线程基本上同时只能运行一个协程,所以从理论上来说协程性能并没有线程好,但在不同的场景应用下还是有些区别的。


Locust的安装

Locust对python2和python3均支持,但现在python2已经不再更新,所以使用python3为主。那么我们要根据实际的压测机器来选择具体的python版本,然后再确定Locust的版本。目前windows7依然有很高的使用率,如果不巧你的压测机器是windows7的话就只能找python3.6的版本(windows7最高支持到3.6),如果不是那么可以选更高的python版本,越新的越稳定的越好。

可以在Locust源码页面里看到各版本的Locust所支持的python版本,https://github.com/locustio/locust。选好版本后就可以进行安装了,根据你是windows还是linux或者mac系统选择合适的安装方式。与python的基本第三方包一样,Locust安装会自动把需要的包都自动安装好,我们需要注意的是有一些第三方包可能跟你的系统相冲突。其中最主要的就是gevent库、greenlet库(这两个是协程相关库,跟性能和稳定性息息相关)、msgpack库(这个在实际中也遇到过)。对这些库可以进行回退或者选择合适的版本,可以在这些第三方库的官方网站找相关线索。直接在python官方网址搜索库名即可,https://www.python.org/

以windows举例,可以使用pip进行安装,在cmd窗口输入如下命令(假设安装的版本是2.4.1):

pip install locust==2.4.1

目前pip国内经常会卡顿,遇上速度较慢可以使用国内镜像源:

pip install locust==2.4.1 -i https://pypi.tuna.tsinghua.edu.cn/simple

安装好之后可以使用pip命令查看locust和其所需要的第三方包版本:

pip -list

locust的源码位置在你的python安装目录下,有时可根据需求进行修改:

C:\Python36\Lib\site-packages\locust

Locust的基本使用

如果是进行简单的Http压测,那么可以从一个简单的HttpLocust入手:

class UserBehavior(TaskSet):
    @task()                
    def init(self):
        ... # 一次http请求

class WebsiteUser(HttpLocust):
    host = '0.0.0.0' # 某个ip或域名
    task_set = UserBehavior # 自己定义的类
    min_wait = 0
    max_wait = 1000

如此,就是一个简单的Locust框架。min_wait和max_wait是必须自定义的,他们代表请求间隔的范围,框架会自动在这个范围里随机一个时间出来。TaskSet和@task是Locust的固定用法,每次每个协程(Locust的用户)会在TaskSet中随机选一个进行执行,Locust也提供顺序TaskSet等不同需求。

写完脚本需要执行起来了,这里就是告诉Locust帮我生成用户进行压测,前面我们已经设置了请求的间隔,那么运行起来之后我们可以设定Locust最终生成多少用户进行请求以及孵化这些用户的效率。

上面的代码我们找一个新的文件保存起来,起个脚本的名字,如some_http_request.py。然后在cmd窗口可输入以下命令:

locust -f some\_http\_request.py --web-host=127.0.0.1

locust有很多种运行方式,可参考官方文档,这里是单机执行,即只有一台压测机情况。同时使用网页开启,开启网页的ip这里是配置在了本机上,可根据需要修改。执行完cmd命令后,可打开浏览器(尽量不要使用ie):127.0.0.1:8089。ip是前面设定的保持一致,端口号则在源码中,如有冲突可以根据需求去源码中修改。打开之后:


locust.png

Nubers of users是总的用户数量,其实就是压测其来之后locust会孵化多少个协程出来进行压测,而Spawn rate则是孵化用户的数量,所以刚开始压测时候你会发现rps可能跟你预设的不符,原因就在这。这里也是方便了测试服务器在刚开始承压和一段时候的承压能力的不同。

压测之后可以从网页上下载压测报告,有实时曲线可以看到response time和rps,有时服务器的承压能力不够会出现response time无限增大或者为0(极少数短时间没有返回),此时rps可能达不到预期或很低甚至接近于0,因为locust总共就会孵化设定好的用户,每个用户都按设定的时间间隔来请求,当本次请求时间过长或者没有返回时候,下次请求就不会发生,所以rps统计会极低。


Locust的多机使用

当压测机不止一台时候,通常情况是因为一台满足不了所需要的性能要求(特别当rps需求过高的时候,需要的协程用户更多),就需要多台机器一起进行压测了。

Locust支持一台master和多台worker(更早版本叫slave)形式。这时候通常压测脚本不要需要变动,在master机器和worker机器上使用不同的cmd命令即可。

master机器上:

locust -f some\_http\_request.py --web-host=127.0.0.1 --master --master-host=127.0.0.1

worker机器上:

locust -f some\_http\_request.py --worker --master-host=127.0.0.1

如果master机器也需要执行压测,即不仅仅是做控制和统计来用,那么也可以执行worker的命令,同时兼有worker的运行。注意检测下压测机器的性能即可,在cpu、内存、硬盘、io等指标上不要超标导致压测结果不准确,这里主要注意的就是cpu和内存。

注意web-host的部署仅仅是配置了控制网页的机器,不要求此机器一定要和master机器一致。特别是在Linux作为压测机器时候,如果把windows机器作为控制页面的机器,master和worker机器都是Linux,就会很方便控制压测和获取报告,这里要注意的就是master、worker和控制页面机器要互相能够ping通。


Locust实际中常见的问题
1. 基于Locust的Http压测

针对Http接口,对服务器进行性能压测或者自动化的接口测试是比较常见的测试内容。Locust对Http接口提供了request库基本请求,并提供了一种FastHttpUser更高效的方案。后者可以参考官方文档https://docs.locust.io/en/stable/increase-performance.html。使用时候直接把HttpUser换成FastHttpUser 即可,访问url一样使用request方法。

# 2. 针对非Http的压测

如前文所述,Locust是一种多协程压测的框架,本质上是利用多协程进行同时间多次(就是所谓的rps或者tps)对接口进行访问,已达到一定的压力。比较常见的就是socket连接,包含Websocket等。那么我们可以选择使用python的第三方socket库进行接口访问,这时只需要把连接的IP、端口号和密钥(如果有)准备好建立好连接,之后进行约定好的请求和接收信息即可。

Locust所提供的内部类在每次的task请求时进行一次,如果task里面我们进行了一次socket请求,那么计算rps或tps就按正常计算即可,如果多次,按照理论加倍。当然与Http请求不一样我们在socket请求之前只需要进行一次建立连接即可,这部分最好不要算到请求时间的计算内,否则会影响rps的统计。

# 3. 关于性能上限

windows的压测机器一个cmd窗户即一个worker里的用户数量不能超过1024,这是由于windows的句柄限制,是无解的。如果不够,可以增加worker数量,但这显然会增加系统开销。worker数量的选择最好与机器的cpu数量一致,因为在locust源码中,worker与worker之间是进程级别,而python会默认把进程尽可能多的分开给cpu,这也可以尽可能多的利用机器资源。

linux就没有这个问题,在linux系统中可以去设置系统句柄限制。普遍来说linux作为压测机比windows性能要好的多。

另一个值得注意的问题则是,在htpp请求中,不同的请求内部会消耗掉不同的端口号(发送端不是接收端,接收端是固定的)。http请求底层是基于tcp的,每次http请求都会经过:建立连接-发送-接收-释放连接,而tcp的设置会决定释放连接的时效问题。如果释放不及时,压测时候同一时间有大量端口占用就可能导致后续请求没有端口了。windows的端口数量最多只有6万多个(这还得在注册表去设置),假设一个连接占用端口时间为3s,那么理论上来讲每秒2万rps就是这台机器的上限了。所以我们这块需要去注册表设置tcp和端口,可参考https://www.jianshu.com/p/00136a97d2d8

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