使用Python的Treq on Twisted来进行HTTP压力测试
作者:goldensun 发布时间:2023-01-26 22:29:28
从事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很优雅、易于使用且强大。这是一个例子:
>>> from treq import get
>>> def done(response):
... print response.code
... reactor.stop()
>>> get("http://www.github.com").addCallback(done)
>>> from twisted.internet import reactor
200
简单的测试脚本
如下是一个使用Treq的简单脚本,用最大可能量的请求来对单一URL进行轰炸。
#!/usr/bin/env python
from twisted.internet import epollreactor
epollreactor.install()
from twisted.internet import reactor, task
from twisted.web.client import HTTPConnectionPool
import treq
import random
from datetime import datetime
req_generated = 0
req_made = 0
req_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 <test@example.com>',
'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()
输出结果:
2013-04-25 09:30 Requests: 327 generated; 153 sent; 153 received
2013-04-25 09:30 Requests: 306 generated; 156 sent; 156 received
2013-04-25 09:30 Requests: 318 generated; 184 sent; 154 received
“Generated”类的数字代表被Twisted反应器准备好但是还没有发送的请求。这个脚本为了简洁性忽略了所有错误处理。为它添加超时状态的信息就留给读者作为一个练习。
这个脚本可以当做是一个起始点,你可以通过拓展改进它来自定义特定应用下的处理逻辑。建议你在改进的时候用collections.Counter 来替代丑陋的全局变量。这个脚本运行在单线程上,想通过一台机器压榨出最大量的请求的话,你可以用类似 mulitprocessing 的技术手段。
愿你乐在压力测试!


猜你喜欢
- 大家都知道,Dreamweaver是是一款专业的网页设计工具,提供了许多方便、实用的功能,使得以前许多网页效果的实现从繁琐的代码
- 问一下谁知道如何用 javascript 获取硬盘信息1.获得硬盘当前有几个盘符.2.每个盘符的 大小,已经使用的大小,和没有使用的大小原理
- import shutil高级的文件,文件夹,压缩包的处理模块,也主要用于文件的拷贝shutil.copyfileobj(fsrc,fdst
- pytorch读取图像数据转成opencv格式方法:先转成numpy通用的格式,再将其转换成opencv格式。pytorch读取的数据使用l
- 一 基本知识millisecond 毫秒microsecond 微秒 nanosecond 纳秒1秒=1000毫秒 1毫秒=1000微秒 1
- 详解python中的文件与目录操作一 获得当前路径1、代码1>>>import os>>>print(&
- 前言调用EXPLAIN可以获取关于查询执行计划的信息,以及如何解释输出。EXPLAIN命令是查看查询优化器如何决定执行查询的主要方法,但该动
- 最近迷上了高效处理数据的pandas,其实这个是用来做数据分析的,如果你是做大数据分析和测试的,那么这个是非常的有用的!!但是其实我们平时在
- 虽然有些人认为区块链是一个早晚会出现问题的解决方案,但是毫无疑问,这个创新技术是一个计算机技术上的奇迹。那么,究竟什么是区块链呢?区块链以比
- 前面也讲过一次phar文件上传的东西,但是那都是过滤比较低,仅仅过滤了后缀。知道今天看到了一篇好的文章如果过滤了phar这个伪造协议的话,那
- 本文实例为大家分享了FormData上传多个文件的具体代码,供大家参考,具体内容如下由于项目中使用到,特此写个Demohtml代码:<
- 1. 为什么要有转义?ASCII 表中一共有 128 个字符。这里面有我们非常熟悉的字母、数字、标点符号,这些都可以从我们的键盘中输出。除此
- numpy对数组求平均时忽略nan值在对numpy数组求平均np.mean()或者求数组中最大最小值np.max()/np.min()时,如
- 本文实例讲述了JS截取与分割字符串的常用方法。分享给大家供大家参考,具体如下:JS截取字符串可使用 substring()或者slice()
- 前言本博客重点内容:reportlab生成流文件格式、reportlab分页和图片流文件写入reportlab等。我讲一下我这个需求的来源,
- 除了数字,Python中最常见的数据类型就是字符串,无论那种编程语言,字符串无处不在。例如,从用户哪里读取字符串,并将字符串打印到屏幕显示出
- Part 1: 简介在PyTorch中,torch.cat()是一个被广泛使用的函数。它可以让我们在某个维度上把多个张量组合在一起。对于那些
- Python之绘图和可视化1. 启用matplotlib最常用的Pylab模式的IPython(IPython --pylab)2. mat
- 本文安装的是pytorch1.4版本(cpu版本)首先需要安装Anaconda是否需要安装基于cuda的PyTorch版本呢?对于普通笔记本
- 关于ref和$refs的用法及讲解,vue.js中文社区( https://cn.vuejs.org/v2/api/#ref )是这么讲解的