使用python requests模块搭建http load压测环境

网上开源的压力测试工具超级的多,但是总有一些功能不是很符合自己预期的,于是自己动手搭建了一个简单的http load的压测环境

1.首先从最简单的http环境着手,当你在浏览器上输入了http://www.google.com并且按下回车的时候其实已经发生了很多事情。

  1.你的PC会去查找本地DNS缓存,查看是否存在www.google.com的IP,一般来说第一次访问是没有的。

  2.于是,你的PC在本地DNS没有查找的IP的情况下,只能去求助于DNS server了(DNS server可以通过命令"ipconfig /all"查看),这个时候通过一系列的DNS query后,PC已经获取到了谷歌的IP了

  3.这时浏览器便会发出第一个报文,TCP SYN与谷歌的服务器建立TCP连接,当你的这个TCP SYN报文的时候,咱们伟大的天朝防火墙把我们的TCP SYN报拦截了!!!,于是浏览器在尝试多次建连为未成功的情况下只能返回给你一个"无法连接到此网站"。

  4.这是一个失败的案例,于是你重新在浏览器中输入了咱们伟大的国产搜索网站http://www.baidu.com

  5.所有的流程和前面是一样的,浏览器发送了TCP SYN,baidu server返回SYN+ACK,浏览器再次回复确认报文ACK,这时你与百度已经建立了一条可靠的连接,双方可以在这条连接里相互发送报文了

2.简单的一个用户访问百度的流程就结束了,但是真实场景是这样的吗?肯定不是啊,天朝上亿网民都需要访问百度来搜索一些在夜深人静的时候偷偷看的爱情动作片,这个时候,baidu server集群的部分成员会感觉身体被掏空了一般,而有一些则感觉还没有被满足,于是在有一款强悍的盾牌叫做web负载均衡,web负载均衡会在baidu server的前面把所有的http request都承包下来,然后挨个发给baidu server的服务器集群,此时的baidu server集群的成员都能得到相应的http request

3.尽管如此,baidu server在正常情况下还是能够很好的工作,可是一旦遇到很大的突发请求流量时就会感觉很难处理过来,比如说某宝的双十一活动,某东的双十二活动,这些都是突发业务流量,此时server们就会感觉接客有点接不过来,所以我们这些作为质量保证的QA测试攻城狮面前,这些都是我们需要解决的,由此就有了咱们的HTTP load测试环境

4.从概念上来说http load就是对web软件进行高负载,高压力,高流量的测试,并且这种测试是很有必要的

5.如何搭建自己所需要的http load压测环境呢

  1.从需求考虑,http request包括哪些内容呢? url, 各种header, cookie, 还有什么auth 等等字段和头部,这些python requests模块都能帮你解决

    def request(self, method, url,
            params=None, data=None, headers=None, cookies=None, files=None,
            auth=None, timeout=None, allow_redirects=True, proxies=None,
            hooks=None, stream=None, verify=None, cert=None, json=None):
        """Constructs a :class:`Request <Request>`, prepares it and sends it.
        Returns :class:`Response <Response>` object.

        :param method: method for the new :class:`Request` object.
        :param url: URL for the new :class:`Request` object.
        :param params: (optional) Dictionary or bytes to be sent in the query
            string for the :class:`Request`.
        :param data: (optional) Dictionary, bytes, or file-like object to send
            in the body of the :class:`Request`.
        :param json: (optional) json to send in the body of the
            :class:`Request`.
        :param headers: (optional) Dictionary of HTTP Headers to send with the
            :class:`Request`.
        :param cookies: (optional) Dict or CookieJar object to send with the
            :class:`Request`.
        :param files: (optional) Dictionary of ``'filename': file-like-objects``
            for multipart encoding upload.
        :param auth: (optional) Auth tuple or callable to enable
            Basic/Digest/Custom HTTP Auth.
        :param timeout: (optional) How long to wait for the server to send
            data before giving up, as a float, or a :ref:`(connect timeout,
            read timeout) <timeouts>` tuple.
        :type timeout: float or tuple
        :param allow_redirects: (optional) Set to True by default.
        :type allow_redirects: bool
        :param proxies: (optional) Dictionary mapping protocol or protocol and
            hostname to the URL of the proxy.
        :param stream: (optional) whether to immediately download the response
            content. Defaults to ``False``.
        :param verify: (optional) Either a boolean, in which case it controls whether we verify
            the server's TLS certificate, or a string, in which case it must be a path
            to a CA bundle to use. Defaults to ``True``.
        :param cert: (optional) if String, path to ssl client cert file (.pem).
            If Tuple, ('cert', 'key') pair.
        :rtype: requests.Response
        """
        # Create the Request.

  2.参数理解:

    1.params={'key1':'value1'},代表的是在url中加入query,也就是查询字符串(具体可以查看HTTP权威指南)

r = requests.get("http://172.16.83.69:80", auth=("taomin","123"), params={'query':'12345'})
print(r.url)

http://172.16.83.69:80/?query=12345

    举个例子你可以在浏览器中输入"http://www.sogou.com/web?query=12345",此时你会发现神奇现象,可以尝试一下,很快就能理解什么是query

 

    2.header={'host':'google'}

    这个字段没什么可以解释的,就是在http请求中添加头部,很好理解

    

    3.cookies={'mycookie':123},cookies是诞生是因为http是无状态的,而cookie则像一张会员卡一样,告诉服务器,我之前来过或者我之前登录过

r = requests.get("http://172.16.83.69:80", auth=("taomin","123"), params={'query':'12345'},cookies={'mycookie':'123'})

     

    4.auth=('user',passwd),这个很有用处,有些网站需要验证你的身份才能登录,此时如果你能够在添加auth头部的话,可以将用户名和密码添加在auth字段中

r = requests.get("http://172.16.83.69:80", auth=("taomin","123"), params={'query':'12345'},cookies={'mycookie':'123'})

     5.post通过data参数传递参数

headers = {"Content-Type":"applicationjson"}
data={
    num:1,
    two:2, 
}
requests.post(headers=headers,url="http://www.baidu.com",data=data)

 

    字段解释大概先这么多了,最后附上自己写的一个简单的python压力测试脚本,I5处理器作为测试的客户端可以打到CPS为1000多吧

# -*- coding: utf-8 -*-
#!/usr/bin/env python
import requests
import threading
import time

header = {'Agent-User':'Chrome'}
start = time.time()

def f():
    while(time.time()-start<100000):
        r = requests.get("http://172.16.83.69:80", auth=("taomin","123"), params={'query':'12345'},cookies={'mycookie':'123'})
        print(r.status_code)

threads = []

for i in range(1000):
    threads.append(threading.Thread(target=f,args=()))

for i in threads:
    i.start()
    i.join()

 使用了多线程增强用户数和并发数,同时打印htt返回状态,确认http访问是否成功

posted @ 2017-12-12 19:21  taomin  阅读(609)  评论(0编辑  收藏  举报