网络编程
位置:首页>> 网络编程>> Python编程>> 使用Python的Treq on Twisted来进行HTTP压力测试

使用Python的Treq on Twisted来进行HTTP压力测试

作者:goldensun  发布时间:2023-01-26 22:29:28 

标签:Python

从事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 的技术手段。

愿你乐在压力测试!

0
投稿

猜你喜欢

  • 一般语言都提供了按字典排序的API,比如跟微信公众平台对接时就需要用到字典排序。按字典排序有很多种算法,最容易想到的就是字符串搜索的方式,但
  • 前言Iframe 是一种将网页嵌入到另一个页面的内容中的方法。这是通过使用 HTML 元素、外部网站的 URL 以及窗口在您的网站上的外观参
  • 外联接。外联接可以是左向外联接、右向外联接或完整外部联接。 在 FROM 子句中指定外联接时,可以由下列几组关键字中的一组指定:LEFT J
  • 目录时间戳相减装饰器timeit模块重复调用 timeit()cProfile性能分析工具时间戳相减在代码执行前后各记录一个时间点,两个时间
  • 如何显示数据库中的图片和超级链接?代码见下:<% set conn=server.creatobject(&quo
  • 在应用SA-FileUp时,必须确认用户已对目的路径有读、写、删除的权力。在多文件上传中,由于浏览器不支持SIZE= 属性,所以对多文件的情
  • 代码如下: Function NumberSplit(num) Dim i,length length=Len(num) For i=1 T
  • 首先要声明一点,大部分情况下,修改MySQL是需要有mysql里的root权限的, 所以一般用户无法更改密码,除非请求管理员。方法一使用ph
  • 因为我们现在的前端框架做性能优化,为了找到各个组件及框架的具体解析耗时,需要在框架中嵌入一个耗时测试工具,性能测试跟不同的计算机硬件配置有很
  • 总有人认为linux搭建php环境很复杂,然后尝试安装lnmp一键安装包。其实说白了就是安装一个web服务器,然后支持php即可,很简单的,
  • 最近,我有机会研究对视觉设计作用的常见误解,这些误解仍然盛行于行政主管、产品主管,工程经理和市场专家中。设计团队成员如何说明这些认识是错误的
  • 看了cragle的《有没有必要将网站Div+Css重构?》的文章,有一些想法不说不快,我也在文章的评论里提到曾经开除过两个执着使用div技术
  • 我们都知道在9i之前,要想获得建表和索引的语句是一件很麻烦的事。我们通常的做法都是通过export with rows=no来得到,但它的输
  • 什么是CSS裸奔节?CSS裸奔节就是将这整站的css样式都去掉,这样所有的布局,颜色,背景什么的就都没有了(除非你使用table布局),只剩
  • 进程进程是程序的一次动态执行过程,它对应了从代码加载、执行到执行完毕的一个完整过程。进程是系统进行资源分配和调度的一个独立单位。进程是由代码
  • 动态语言与静态语言有很多不同,最大的特性之一就是可以实现动态的对类和实例进行修改,在Python中,我们创建了一个类后可以对实例和类绑定心的
  • 1、使用索引来更快地遍历表。缺省情况下建立的索引是非群集索引,但有时它并不是最佳的。在非群集索引下,数据在物理上随机存放在数据页上。合理的索
  • django中,很多时候我们都需要有一个地方来进行更加详细的权限控制,例如说哪些用户可以访问哪些页面,检查登录状态等,这里的话就涉及到了中间
  • 输入汉字提示拼音,试试下面这个函数,不知是不是你要的那个:查询汉字便宜到词典网<%function getpychar(ch
  • MySQL分区方便了我们的使用,但是MySQL分区究竟能做些什么,MySQL分区有没有什么限制呢?阅读下文,您就能找到答案。MySQL分区能
手机版 网络编程 asp之家 www.aspxhome.com