WRK+fabric进行集群部署和压测

http://blog.csdn.net/ronghuanye/article/details/72955739


一、   wrk部署

1、部署控制机

需要一台机器安装fabric和wrk作为控制机。

(1)安装fabric

第一步:将fabric.rar解压缩后把整个目录上传到控制机的/home目录下

安装包:

cffi-1.9.1.tar.gz
cryptography-1.6.tar.gz
ecdsa-0.13.tar.gz
enum34-1.1.6.tar.gz
Fabric-1.12.0.tar.gz
gmp-6.0.0a.tar.bz2
idna-2.1.tar.gz
install.sh
ipaddress-1.0.17.tar.gz
libffi-devel-3.0.5-3.2.el6.x86_64.rpm
openssl-1.0.2.tar.gz
paramiko-1.15.2.tar.gz
pyasn1-0.1.9.tar.gz
pycparser-2.17.tar.gz
pycrypto-2.6.1.tar.gz
Python-2.7.11.tgz
setuptools-30.2.0.tar.gz
six-1.10.0.tar.gz
zlib-1.2.3-29.el6.x86_64.rpm
zlib-devel-1.2.3-29.el6.x86_64.rpm

自动安装脚本install.sh

#!/bin/bash
#将python环境升级到2.7.11
rpm -ivh zlib-1.2.3-29.el6.x86_64.rpm
rpm -ivh zlib-devel-1.2.3-29.el6.x86_64.rpm
tar -xvf Python-2.7.11.tgz
cd Python-2.7.11
./configure
make all
make install
make clean
make distclean
mv /usr/bin/python /usr/bin/python_old
ln -s /usr/local/bin/python2.7 /usr/bin/python
cd ..


#安装fabric模块
tar -xvf gmp-6.0.0a.tar.bz2
cd gmp-6.0.0
./configure
make
make check
make install
cd ..
tar -xvf  setuptools-30.2.0.tar.gz
cd setuptools-30.2.0
python setup.py build
python setup.py install
cd ..
tar -xvf pycrypto-2.6.1.tar.gz
cd pycrypto-2.6.1
export ac_cv_func_malloc_0_nonnull=yes
python setup.py build
python setup.py install
cd ..
tar -xvf pyasn1-0.1.9.tar.gz
cd pyasn1-0.1.9
python setup.py build
python setup.py install
cd ..
rpm -ivh libffi-devel-3.0.5-3.2.el6.x86_64.rpm
tar -xvf pycparser-2.17.tar.gz
cd pycparser-2.17
python setup.py build
python setup.py install
cd ..
tar -xvf cffi-1.9.1.tar.gz
cd cffi-1.9.1
python setup.py build
python setup.py install
cd ..
tar -xvf openssl-1.0.2.tar.gz
cd openssl-1.0.2
./config --prefix=/usr/local/openssl-1.0.2 shared zlib-dynamic enable-camellia
make && make install
ln -s /usr/lib64/libssl.so.1.0.1e /usr/lib64/libssl.so
ln -s /usr/lib64/libcrypto.so.1.0.1e /usr/lib64/libcrypto.so
cd ..
tar -xvf ipaddress-1.0.17.tar.gz
cd ipaddress-1.0.17
python setup.py build
python setup.py install
cd ..
tar -xvf enum34-1.1.6.tar.gz
cd enum34-1.1.6
python setup.py build
python setup.py install
cd ..
tar -xvf six-1.10.0.tar.gz
cd six-1.10.0
python setup.py build
python setup.py install
cd ..
tar -xvf idna-2.1.tar.gz
cd idna-2.1
python setup.py build
python setup.py install
cd ..
tar -xvf cryptography-1.6.tar.gz
cd cryptography-1.6
export C_INCLUDE_PATH=/usr/local/openssl-1.0.2/include
export CPLUS_INCLUDE_PATH=/usr/local/openssl-1.0.2/include
python setup.py build
python setup.py install
cd ..
tar -xvf ecdsa-0.13.tar.gz
cd ecdsa-0.13
python setup.py build
python setup.py install
cd ..
tar -xvf paramiko-1.15.2.tar.gz
cd paramiko-1.15.2
python setup.py build
python setup.py install
cd ..
tar -xvf Fabric-1.12.0.tar.gz
cd Fabric-1.12.0
python setup.py build
python setup.py install
cd ..

第二步:进入/home/fabric目录,给install.sh文件赋执行权限,然后执行

cd/home/fabric

chmod u+x install.sh

./install.sh

脚本执行完成后查看是否报错,如果报错根据错误信息修正后,再执行脚本。

第三步:验证fabric是否安装成功

python -c "from fabric.api import * ; print env.version"

在控制机上执行上面的命令,显示出版本说明安装成功

如果报错:ERROR:root:code for hash md5 was not found

执行下面命令即可

python

>>>import_hashlib

(2)安装wrk

第一步:将wrk-master.zip上传到控制机的/home目录下,执行解压缩命令

cd/home

unzipwrk-master.zip

第二步:进入/home/wrk-master目录,执行安装命令

cdwrk-master

make

编译完成之后会在/home/wrk-master目录中生成wrk二进制文件。

第三步:上传delayx.lua文件到控制机的/home/wrk-master/scripts目录下

delayx.lua文件

function delay()
   return math.random(${thinktime}, ${thinktime})
end

第四步:上传controller.py、ReadHost.py、clienthosts.txt三个文件到控制机的/home目录下

controller.py文件

#!/usr/bin/python
# -*- coding:utf-8 -*-


from ReadHost import *
from fabric.api import *
from fabric.colors import *
from fabric.context_managers import *
from fabric.state import env
import re
import os
import sys
import datetime
#run test entrance,defin necessary parameter
def runtest():
    test_name="test_001" #test case name
    threads=4            #numbers of thread of every client host
    connections=4        #numbers of connection of every client host
    durations=10         #time of test case running
    thinktime=2000       #the time interval between requests
    url="http://10.41.150.52:8082/job/tcep/"  #request URL


    dt = datetime.datetime.now()
    res_file = "/home/test_result/%s_%s.txt"%(test_name,dt)
    res_file = res_file.replace(" ","_")
    if os.path.exists("/home/test_result"):
        with settings(hide('warnings', 'running', 'stdout', 'stderr'), warn_only=True):
            local("touch %s"%res_file)
    else:
        with settings(hide('warnings', 'running', 'stdout', 'stderr'), warn_only=True):
            local("mkdir /home/test_result&&touch %s"%res_file)
    with settings(hide('warnings', 'running', 'stdout', 'stderr'), warn_only=True):
        execute(runwrk,threads,connections,durations,url,test_name,thinktime,res_file)
    with open(res_file,'r') as f:
        counts = f.readlines() 
if counts:
  ltc = CountLTC(res_file)
  tps = CountTPS(res_file)
  io = CountIO(res_file)
  print yellow('Total => [90Percent Latancy:%s] [TPS:%s] [IO:%s]'%(ltc,tps,io))
  with settings(hide('warnings', 'running', 'stdout', 'stderr'), warn_only=True):
      local("echo 'Total => [90Percent Latancy:%s] [TPS:%s] [IO:%s]' >> %s"%(ltc,tps,io,res_file)) 
#get client host IP list
env.roledefs['wrk'] = HostList
#get client host password list
env.passwords = HostPswList
#get result function
def GetWrkResult(text):
    p1 = '.+?90%\s+(?P<latancy90>\d+\.?\d+\w+)'
    p2 = 'Requests/sec:\s+(?P<tps>\d+\.?\d+)'
    p3 = 'Transfer/sec:\s+(?P<tps_io>\d+\.?\d+\w+)'
    ret = {}
    m1 = re.search(p1,text)
    m2 = re.search(p2,text)
    m3 = re.search(p3,text)
    if m1:
    ret['latancy90'] = m1.group("latancy90")
    ret['tps'] = m2.group("tps")
    ret['io'] = m3.group("tps_io")
    return ret
#deploy wrk to all client host
@roles("wrk")
@parallel(pool_size=30)
def deploywrk():
    with settings(hide('warnings', 'running'), warn_only=True):
        run("mkdir -p /home/wrk-master/scripts")
        put("/home/wrk-master/wrk","/home/wrk-master/")
        run("chmod u+x /home/wrk-master/wrk")
        put("/home/wrk-master/scripts/*","/home/wrk-master/scripts/")
        
#begin to run wrk command in all client host
@roles("wrk")
@parallel
def runwrk(threads,connections,durations,url,test_name,thinktime,res_file):
    if threads>connections:
print red("%s:number of connections must be >= threads"%env.host)
return
    if thinktime:
        CMD = "./wrk -t{th} -c{con} -d{dur}s -T30s --script=./delay.lua --latency {test_url}".format(th=threads,con=connections,dur=durations,test_url=url)
    else:
        CMD = './wrk -t{th} -c{con} -d{dur}s -T30s --latency {test_url}'.format(th=threads,con=connections,dur=durations,test_url=url)
        host_speed_type = list(host_speed_type_define.keys())[list(host_speed_type_define.values()).index(env.host)]
        thinktime = speed_type_define[host_speed_type]
        
    WRKDIR = '/home/wrk-master/'
    with cd(WRKDIR):
        print green('%s:start testing with wrk ...'%env.host)
        run("export thinktime=%d&&envsubst '${thinktime}'<./scripts/delayx.lua >delay.lua"%thinktime)
        run(CMD + ">%s_%s.result"%(test_name,env.host))
        run("rm -f delay.lua")
        wrk_ret = GetWrkResult(run("cat %s_%s.result"%(test_name,env.host)))
if wrk_ret:
   tmp = '{wrkhost} => [90Percent Latancy:{latancy}] [TPS:{tps}] [IO:{io}] [URL:{test_url}]'.format(wrkhost = env.host,latancy = wrk_ret["latancy90"],tps = wrk_ret["tps"],io = wrk_ret["io"],test_url = url)
   local("echo '%s' >> %s"%(tmp,res_file))
            print yellow('{wrkhost} => [90Percent Latancy:{latancy}] [TPS:{tps}] [IO:{io}] [URL:{test_url}]'.format(wrkhost = env.host,latancy = wrk_ret["latancy90"],tps = wrk_ret["tps"],io = wrk_ret["io"],test_url = url))
else:
   print red("%s:test result is empty!"%env.host)


#count 90Percent Latancy average
def CountLTC(resultfile):
    with open(resultfile,'r') as f:
        reslist = f.readlines()  
        reslist = [ s[0] for s in [(res.split('Latancy:')[1].split('] [TPS')) for res in reslist]]
total = 0
for time in reslist:
   if time.count('us'):
total = total + float(time.split('.')[0])/1000
   else:
if time.count('ms'):
   total = total + float(time.split('ms')[0])
else:
   total = total + float(time.split('m')[0])*1000
        return str(round(total/len(reslist),2)) + 'ms'
#count total TPS
def CountTPS(resultfile):
    with open(resultfile,'r') as f:
        reslist = f.readlines()
        reslist = [ s[0] for s in [(res.split('[TPS:')[1].split('] [IO')) for res in reslist]]
        total = 0
        for tps in reslist:
            total = total + float(tps)
        return total
#count total IO
def CountIO(resultfile):
    with open(resultfile,'r') as f:
        reslist = f.readlines()
        reslist = [ s[0] for s in [(res.split('[IO:')[1].split('] [URL')) for res in reslist]]
        total = 0
containMB = False
for io in reslist:
            if io.count('MB'):
containMB = True
if containMB:
            for io in reslist:
if io.count('MB'):
                    total = total + float(io.split('MB')[0])
else:
   if io.count('KB'):
                        total = total + float(io.split('KB')[0])/1024 
else:
   for io in reslist:
    if io.count('KB'):
                    total = total + float(io.split('KB')[0])
if containMB:
   return str(round(total,2)) + 'MB'
else:
            return str(round(total,2)) + 'KB'

ReadHost.py文件

#!/usr/bin/python
# -*- coding:utf-8 -*-
#read client host IP list from clienthost file
#format:['root@10.41.150.177:22', 'root@10.41.139.175:22']
def GetHostList(hostfile):
    with open(hostfile,'r') as f:
        iplist = f.readlines()  
        iplist = [ 'root@' + s[0] + ':22' for s in [(ip.split('\t')) for ip in iplist]]
        return iplist
        
#read client host password list from clienthost file
#format:{ 'root@10.41.150.208:22': 'c3E#6Jt(fB6PPj','root@10.41.139.175:22':'TNScP56m#nr2*K'}
def GetHostPswList(hostfile):
    with open(hostfile,'r') as f:
        iplist = f.readlines()  
        iplist = [(ip.split('\t')) for ip in iplist]
        psw_dic = {}
        for s in iplist:
            psw_dic['root@' + s[0] + ':22'] = s[1].strip()
        return psw_dic


HostList = GetHostList("clienthosts.txt")
HostPswList = GetHostPswList("clienthosts.txt")


if __name__ == '__main__':
    print HostList
    print HostPswList

clienthosts.txt文件

10.41.26.162  QEn68(Bmy$k7PW
10.41.26.164 Rsf!QB7Qgj7A!3

 

2、部署压力机

使用多台机器作为压力机,可以使用已经部署好的控制机来部署wrk到所有的压力机。

(1)部署wrk工具

(此步骤执行一次即可,如果要添加压力机,需要再执行一次)

第一步:远程登录控制机,进入/home 目录

第二步:修改clienthosts.txt文件,添加压力机IP地址和对应的root登录密码,格式如下:

10.41.150.50  AWd(g8hW(QYs62

10.41.150.51  ViLjBp858_H#yB

注意:1、IP和密码之间用tab符隔开

2、最后一条记录不要换行,即不能存在空行

第三步:执行命令fab -fcontroller.py deploywrk

执行命令过程检查是否有报错

 

二、   Wrk集群压测

1、wrk工具测试框架说明

使用1台机器作为控制机(部署fabric,控制其他压机机并行执行wrk脚本,收集其他压力机执行结果并在控制机显示测试结果),使用多台机器作为机器压力测试机(部署wrk工具,执行wrk命令向服务器发送http/https请求);在所有压力测试机上部署wrk工具或者执行wrk命令都是通过控制机的python脚本controller.py 实现。

 

2、执行集群并发测试

第一步:远程登录控制机,进入/home 目录

第二步:修改controller.py脚本,根据需要修改下面的参数:

test_name=”test_001” 测试场景名称,可以自定义

threads=4           每台压力机启动线程数,最好和机器的CPU个数保持一致

connections=1000   每台压力机创建的连接数,必须大于或者等于启动线程数

durations=60    测试脚本运行时长,单位秒

thinktime= 2000  思考时间,每次请求的时间间隔,单位毫秒

url=”https://www.test.com/”   请求发送的地址


第三步:启动集群并发测试,执行命令fab -f controller.py runtest

执行过程监控是否有报错

 

第四步:查看测试结果,执行完成后控制机上会打印每台压力机的测试结果和总体统计结果

结果格式:压机机ip => [百分之90响应时间][TPS] [每秒网络IO] [测试地址]

测试结果同时保存在/home/test_result/目录下面,文件名格式为:测试场景名称_年月日_时分秒.txt
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值