使用 Twisted Python 和 Treq 进行 HTTP 压力测试
admin
2023-07-31 00:37:35
0

从事API相关的工作很有挑战性,在高峰期保持系统的稳定及健壮性就是其中之一,这也是我们在Mailgun做很多压力测试的原因。

这么久以来,我们已经尝试了很多种方法,从简单的ApacheBench到复杂些的自定义测试套。但是本贴讲述的,是一种使用python进行“快速粗糙”却非常灵活的压力测试的方法。

使用python写HTTP客户端的时候,我们都很喜欢用
Requests library。这也是我们向我们的API用户们推荐的。Requests 很强大,但有一个缺点,它是一个模块化的每线程一个调用的东西,很难或者说不可能用它来快速的产生成千上万级别的请求。

Treq on Twisted简介

为解决这个问题我们引入了Treq (Github库)。Treq是一个HTTP客户端库,受Requests影响,但是它运行在Twisted上,具有Twisted典型的强大能力:处理网络I/O时它是异步且高度并发的方式。

Treq并不仅仅限于压力测试:它是写高并发HTTP客户端的好工具,比如网页抓取。Treq很优雅、易于使用且强大。这是一个例子:

1234567891011 >>> from treq import get >>> def done(response):...     print response.code...     reactor.stop() >>> get(\”http://www.github.com\”).addCallback(done) >>> from twisted.internet import reactor>>> reactor.run()200

简单的测试脚本

如下是一个使用Treq的简单脚本,用最大可能量的请求来对单一URL进行轰炸。

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 #!/usr/bin/env pythonfrom twisted.internet import epollreactorepollreactor.install() from twisted.internet import reactor, taskfrom twisted.web.client import HTTPConnectionPoolimport treqimport randomfrom datetime import datetime req_generated = 0req_made = 0req_done = 0 cooperator = task.Cooperator() pool = HTTPConnectionPool(reactor) def counter():    \’\’\’This function gets called once a second and prints the progress at one    second intervals.    \’\’\’    print(\”Requests: {} generated; {} made; {} done\”.format(            req_generated, req_made, req_done))    # reset the counters and reschedule ourselves    req_generated = req_made = req_done = 0    reactor.callLater(1, counter) def body_received(body):    global req_done    req_done += 1 def request_done(response):    global req_made    deferred = treq.json_content(response)    req_made += 1    deferred.addCallback(body_received)    deferred.addErrback(lambda x: None)  # ignore errors    return deferred def request():    deferred = treq.post(\’http://api.host/v2/loadtest/messages\’,                         auth=(\’api\’, \’api-key\’),                         data={\’from\’: \’Loadtest \’,                               \’to\’: \’to@example.org\’,                               \’subject\’: \”test\”},                         pool=pool)    deferred.addCallback(request_done)    return deferred def requests_generator():    global req_generated    while True:        deferred = request()        req_generated += 1        # do not yield deferred here so cooperator won\’t pause until        # response is received        yield None if __name__ == \’__main__\’:    # make cooperator work on spawning requests    cooperator.cooperate(requests_generator())     # run the counter that will be reporting sending speed once a second    reactor.callLater(1, counter)     # run the reactor    reactor.run()

输出结果:

123 20130425 09:30 Requests: 327 generated; 153 sent; 153 received20130425 09:30 Requests: 306 generated; 156 sent; 156 received20130425 09:30 Requests: 318 generated; 184 sent; 154 received

“Generated”类的数字代表被Twisted反应器准备好但是还没有发送的请求。这个脚本为了简洁性忽略了所有错误处理。为它添加超时状态的信息就留给读者作为一个练习。

这个脚本可以当做是一个起始点,你可以通过拓展改进它来自定义特定应用下的处理逻辑。建议你在改进的时候用 collections.Counter 来替代丑陋的全局变量。这个脚本运行在单线程上,想通过一台机器压榨出最大量的请求的话,你可以用类似 mulitprocessing 的技术手段。

愿你乐在压力测试!


相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
项目管理和工程管理的区别 项目管理 项目管理,顾名思义就是专注于开发和完成项目的管理,以实现目标并满足成功标准和项目要求。 工...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
Python随手笔记第一篇(2... Python中,列表和元组是一种数据结构:序列,序列中的每个元素都被分配一个序号,元素的位置,第一原...
python返回昨天日期的方法 本文实例讲述了python返回昨天日期的方法。分享给大家供大家参考。具体实现方法如下: #-*-co...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
Apache Doris 常见... 什么是 Apache Doris Apache Doris 是一款 MPP 架构的 OLAP 列式存...
在SSIS 中使用 Web S... Web Service简介 Web Service是一种构建应用程序的普遍模型,可以在任何支持网络通...