python高并发压力测试_使用Python的Treq on Twisted来进行HTTP压力测试
发布日期:2021-10-31 18:34:33 浏览次数:25 分类:技术文章

本文共 2921 字,大约阅读时间需要 9 分钟。

从事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很优雅、易于使用且强大。这是一个例子:

1

2

3

4

5

6

7

8

9

10

>>>from treqimport get

>>>def done(response):

...print response.code

... reactor.stop()

>>> get("http://www.github.com").addCallback(done)

>>>from twisted.internetimport reactor

200

简单的测试脚本

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

#!/usr/bin/env python

from twisted.internetimport epollreactor

epollreactor.install()

from twisted.internetimport reactor, task

from twisted.web.clientimport HTTPConnectionPool

import treq

import random

from datetimeimport 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 ',

'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()

输出结果:

1

2

3

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

愿你乐在压力测试!

转载地址:https://blog.csdn.net/weixin_40006779/article/details/110343466 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:python实现匿名发邮件_Python写自动化之邮件发送(匿名)
下一篇:python 调用 c_Python调用C模块(一):C api方式

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月10日 12时50分44秒