并发测试小脚本

由于工作需要,设计了Linux shell编写的并发测试小脚本

contest.sh

#!/bin/shell
#author:liujunbing
#contest.sh

usage="
Usage: $0 [options...] --<num of thread> <curl commend>\n  
Options:\n  
 -h This help text\n  
 -t <num> The seconds that continue the request\n
 -c <num> The count that send the request\n
 注意:此脚本不舍和响应在毫秒级别的并发测试,当响应小于10ms时压力上不来!
"

function testinseconds
{
    startdate=`date +%s`
    enddate=0
    continuetime=0
    a=1
    runtime=$1
    shift
    con=$1
    connum=$(($1+3))#这里由于执行ps -ef|grep curl 会有grep curl 和脚本执行另外一行换行。所以需要加上3
    shift
    echo 测试开始
    while [ $continuetime -le $runtime ]
    do
        if [ $a -lt $connum ]
        then 
            cmd="$@ -s -w  %{time_namelookup}::%{time_connect}::%{time_starttransfer}::%{time_total}::%{http_code}'\n' >>output-$con-$runtime.log &"
            for((i=0; i<=$con/5;i++))
            do
                eval $cmd
                counts=$[ $counts+1 ]
            done

        fi
        a=`ps -ef|grep curl|wc -l`
        enddate=`date +%s`
        continuetime=$(($enddate-$startdate))
    done 
    c=4
    while [ $c -gt 3 ]
    #在执行相应时间后停止发送请求,等待剩下响应收到结果
    do
        usleep 10000
       c=`ps -ef|grep curl|wc -l`
    done 
    enddate=`date +%s`
    continuetime=$(($enddate-$startdate))
}

function testincounts
{
    startdate=`date +%s`
    a=1
    counts=0
    allnum=$1
    shift
    con=$1
    connum=$(($1+3))
    shift
    echo 测试开始
    while [ $counts -lt $allnum ]
    do
        if [ $a -lt $connum ]
        then 
            cmd="$@ -s -w %{time_namelookup}::%{time_connect}::%{time_starttransfer}::%{time_total}::%{http_code}'\n'  >>output-$con-$allnum.log &"       
            for((i=0; i<=$con/10;i++))
            do 
                eval $cmd
                counts=$[ $counts+1 ] 
            done  
        fi
        a=`ps -ef|grep curl|wc -l`
    done
    c=4
    while [ $c -gt 3 ]
    do
        c=`ps -ef|grep curl|wc -l`
        usleep 10000
    done
    enddate=`date +%s`
    continuetime=$(($enddate-$startdate))
}


if [ $# -lt 1 ]
then 
    echo -e $usage
    exit 1
fi

seconds=0
count=0
keepdata=0
while getopts "t:c:hd" arg
do
    case $arg in
        t)
            if [ $count -ne 0 ]
            then 
                echo "-t and -c can't together"
                echo -e $usage
                exit 1
            fi
            seconds=$OPTARG
            if [ $seconds -lt 10 ]
            then 
                seconds=10
            fi
            ;;
        c)
            if [ $seconds -ne 0 ]
            then 
                echo "-t and -c can't together"
                echo -e $usage
                exit 1
            fi
            count=$OPTARG
            if [ $count -lt 10 ]
            then 
                count=10
            fi
            ;;
        h)
            echo -e $usage
            exit
            echo "Unknow argument"
            exit 1
            ;;
        d)
            keepdata=1
        esac
done

if [ $keepdata -eq 1 ]
then 
    shift
fi

if [ $seconds -ne 0 -a $count -eq 0 ]
then 
    continuetime=1
    testinseconds $seconds $3 "$4"
    echo 并发数:$3,持续时间: $continuetime's' 请求:$4>>testresult.log
    gawk -v continuetime=$continuetime -f dataAnalysy.sh output-$3-$seconds.log >>testresult.log
    echo --------------------------------------------------------------------->>testresult.log
    if [ $keepdata -ne 1 ]
    then  
        rm output-$3-$seconds.log
    fi
elif [ $count -ne 0 -a $seconds -eq 0 ]
then
    continuetime=1
    testincounts $count $3 "$4"
    echo 并发数:$3, 请求 :$4>>testresult.log
    gawk -v continuetime=$continuetime -f dataAnalysy.sh output-$3-$count.log >>testresult.log
    echo --------------------------------------------------------------------->>testresult.log
    if [ $keepdata -ne 1 ]
    then    
        rm output-$3-$count.log
    fi 
else
    echo -e $usage
    exit 1
fi
echo 测试结束,结果请查看testresult.log文件
exit 0

dataAnalysy.sh

#!/bin/awk

BEGIN{
FS="::";
OFS="   ";
print "请求总数","成功数","失败数","失败率(小数)","平均响应时间","事物数tps"
i=0;
j=0;
}
{
if($5~/^([0-9])+$/){
   j++
   if($5==200){
      alltime+=$4
      i++;
   } 
}
}
END{
error=j-i;
printf "%-10d %-9d %-9d %-9f    %-15f %-12f\n", j,i,j-i,error/j,alltime/j,j/continuetime
}

************************使用方法************************
1.准备工作
将contest.sh dataAnalysy.sh放在同一个目录下(建议新建一个目录,还有测试结果文件在吃目录中生成)

2.执行脚本
(1)在规定时间完成固定并发的方法
sh contest.sh -t 300 20 "curl ..."
(2)以固定的并发完成多少次请求
sh contest.sh -c 10000 20 "curl ..."
(3)保留测试响应数据
sh contest.sh -d -t/c "curl ..."

3.产看结果
到当前目录查看testresult.log查看数据分析结果


**********************脚本原理*******************************
1.并发:服务器同时处理的请求数(时刻)
2.平均响应时间:请求响应时间之和/请求数之和
3.错误数:数据分析脚本是根据响应状态码200 来判断的。若请求特殊,可以修改dataAnalysys.sh
4.tps/每秒事物数:每秒处理请求的个数

5.脚本通过后台发送curl命令作为基础。通过ps -ef |grep curl|wc -l(去除正在运行脚本和
grep curl命令本身得到的就是后台运行的请求) 监控后台运行的请求数。将响应数据重定向到
"output-并发数-时间/请求次数.log" 文件中


*************************注意事项*****************************
1.curl必须经过测试通过才能运行此脚本。例如带文件的需要文件位置正确
2.ps -ef本省有时间,所以当请求响应在10ms左右,压力加载不上来,请反馈给我修改脚本参数
3.添加-d参数后将脚本执行完成,将响应数据导出到新文件夹并重命名。源文件删除。以免影响
后面的数据结果(output-并发数-时间/请求次数.log这个区分度不是很大)
脚本运行完成,数据分析同时完成查看testresult.log文件。
4.最大并发确定技巧:1.错误率为0,2.tps随并发曲线最高点
最佳并发确定技巧:tps随并发曲线的拐点或者平均响应时间随并发数曲线的拐点。

posted @ 2017-10-24 14:22  孤熵  阅读(416)  评论(0编辑  收藏  举报