移动测试基础 Python 实现通过服务器接口做多线程并发测试

周小丽 · 2015年09月28日 · 最后由 周小丽 回复于 2015年10月14日 · 2508 次阅读

Python 实现通过服务器接口做多线程并发测试

每秒启动一线程,待 50 个线程都启动后,并发向服务器接口以特定的 HTTP 包协议发送消息,核查 HTTP 的响应状态以及响应时间。

#!/usr/bin/env python
#coding=utf8

import httplib, urllib,time,datetime
import thread
#outFile= open("/home/zhouxiaoli/output/MD_Login_2.txt","w")
outFile= open("D:\\MD_Login_2.txt","w")
def upload(no,interval):     
    httpClient = None
    params = urllib.urlencode({'feel':'2','content': 'zhouxiaoli123','hidden':'0','disid':'2'})
    headers = {"Content-type": "application/x-www-form-urlencoded"
                    , "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
                    ,"Cookie": "PHPSESSID=pmau7lj2vmbu1mf7ef0hkp46k0; docdocuid=10088; dochead=Uploads%2FChat%2F2015-05-26%2Fa835acf71b39dedf646204d654f04bd6_thumb.jpg; think_language=zh-CN"
                    ,"User-Agent": "Mozilla/5.0 (Linux; Android 4.4.2; HUAWEI MT7-UL00 Build/HuaweiMT7-UL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36"}

    print "the Thread sleep  %d sec\n" %(50-no)
    time.sleep(50-no) 
    httpClient = httplib.HTTPConnection("app1.qshealthcare.com", 80, timeout=30)
    httpClient.request("POST", "/doctor.php?m=Doctor&c=weibo&a=addweibo", params, headers)
    #需要记录当前时间
    begin = datetime.datetime.now()
    print begin
    response = httpClient.getresponse()
    #需要记录响应时间
    end =  datetime.datetime.now()
    print "the Thread sleep  %s sec\n" %(end-begin)
    outFile.write(str(end-begin)+',')
    print response.status
    outFile.write(str(response.status)+'\n')
    print response.reason
    print response.read()
    #print response.getheaders
    while 1: 
        time.sleep(1)  
def test():
     i=0
     while 1:
          i+=1
          if i < 50:
             thread.start_new_thread(upload,(i,i,))
          else:
             i=0
             time.sleep(3)
          time.sleep(1)

test()
outFile.close()
共收到 16 条回复 时间 点赞

多线程的资料,顶!d=====( ̄▽ ̄*) b

赞一个~
请问 upload 方法最后两行 while 1: time.sleep(1) 是为了什么考量?

@shixue33,每秒启动一个线程,依次启动 50 个线程

感谢分享。

#3 楼 @xiaoli 还是没太看懂,在 test 函数里面不是实现的是每秒启动一个,依次启动的 50 个线程么,那 upload 方法里的一直循环 sleep 是什么意思?

#5 楼 @yjjhappy 同问。
话说这个程序是遇到 Ctrl + C 才会退出的吧?所有 while 1 里都没看到 break 。

#3 楼 @xiaoli 每秒启动一个线程,一次启动 50 个线程,不是写在 test 里边了吗?
我猜 upload 的最后两行代码可能是多余的,否则会让一个线程里边执行完该有的操作以后一直无法结束,平白占了资源

写文件的语句最好整合到一句话中,否则多个线程同时写,顺序会乱掉

@shixue33 @yjjhappy @chenhengjie123 线程内部,如果没有这个 WHILE 的话,线程就退出了。功能没有太完善,在线程里面还可以做其他的功能(比如:每秒定期做一些日志输出,做一些功能执行啊 )

class base_thread(threading.Thread):
    def __init__(self, func):
        threading.Thread.__init__(self)
        self.func = func
        #print(type(self.func))
    def run(self):
        self.func

def multi_thread():
    threads = []
    for i in range(0, int(br["count"])):
        threads.append(base_thread(sample_request(index=i)))
    for j in range(0, int(br["count"])):
        threads[j].start()
    for k in range(0, int(br["count"])):
        threads[k].join()

def sample_request(index=0):
    h = http_request(base_url=br['baseurl'], http_api=br['httpapi'], method=br['method'], http_params=br['postparams'])
    res = h.request()
    http_params['request_num'].append(index+1)
    if res:
        res = '%.2f'%res
        #print(res)
        http_params['response_time'].append(res)

    else:
        http_params['response_time'].append("0")
    if index == int(br['count']) - 1: #如果循环总数循环结束,进行统计操作


class http_request:
    def __init__(self, base_url='XXXX', http_port=None, http_api='XXXXX method='post', http_params=None):
        self.banse_url = base_url
        self.http_port = http_port
        self.http_api = http_api
        self.http_method = method
        self.http_params = http_params
        if http_port == "0":
            self.http_port = None
        else:
            self.http_port = http_port
    def request(self):
        print(HTTP + self.banse_url + self.http_api)
        hc.list_arg.append((HTTP + self.banse_url + self.http_api))
        try:
            http_headers = {'Content-Type': 'application/x-www-form-urlencoded', 'Connection': 'Keep-Alive',
                            'Referer': HTTP + self.banse_url, 'Accept': 'text/plain'}
            # http_params = urllib.parse.urlencode(params)
            http_conn = http.client.HTTPConnection(self.banse_url, self.http_port)
            start_time = time.time()
            http_conn.request(method=self.http_method, url=self.http_api, body=self.http_params, headers=http_headers)
            http_response = http_conn.getresponse()
            if http_response.status == 200:
                print(u"响应时间" + str(time.time() - start_time))
                hc.response_time.append("%.2f" %(time.time() - start_time))
                return time.time() - start_time
                #return http_response.read().decode('utf-8')
            else:
                print(u"请求失败")
                print(http_response.status)
                hc.response_time.append(0)
                return False
        except socket.error:
                print(u"请求超时")
                hc.response_time.append(0)
                print(socket.error)
                return False
        finally:
            http_conn.close()

曾经学习过着方面的知识,多线程接口压力测试,最后结果生成甘特图,使用的是 matplotlib

#7 楼 @shixue33 是的, 最后两行代码目的估计是运行保持线程数. 实际上主流程的代码执行完毕, 充数是没意义的. 因为实际上它是没用的. 也达不到类似 loadrunner 那样的聚合点. 如果想模拟并发, 你应该设置一个聚合点, 让 50 个线程先启动, 然后再 hold, 等待一个全局的条件满足后再执行. 在启动 50 个线程后再设置某个条件. 这样所有线程才会真的并发执行, 并发度才较为理想.

@seveniruby ,主函数中 time.sleep(50-no) ,就是依序等待启动 50 个线程,待都启动完毕后,同时并发执行 upload 中 POST 事件

匿名 #13 · 2015年10月09日

收藏了

先收藏,慢慢学习!

我想问问这个 test() 方法怎么停下来

@turinblueice 目前就不让 test() 停下来,目的测试服务器的最大压力,只有当出现异常了,才会停下来

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册