近期要完成一个涉及呼叫的项目,需要支持访客直接联系客服的功能。
对于测试来说,也需要测试呼叫转发的性能,访客直接拨打接入号,由callserver这边添加路由转发到客服这边。
考虑过使用sipp与winsip两个工具,sipp的话可以自己定制流程,winsip的话可能适合配置型,但是也有很多流程可以配置的,由于以前项目也用过sipp来测试sip消息收发,呼叫也确定使用sipp来测试性能,当然,功能测试也可以用这个,不过功能测试一般直接装个eyebeam来拨就好了。。。
环境:单台服务器部署callserver,另外一台作为sipp的uac以及uas,可以同时运行uac和uas,开两个窗口就好了。
按照以往经验,测试环境系统能够支撑60个坐席,平均每个坐席通话时间60s,系统每秒处理的呼叫量为 60坐席/60s=1 CAPS。
设置3组测试数据:以60个坐席为基准,测试60个坐席以内,60个坐席以上,大于60坐席压力测试。
50坐席容量:0.83 CAPS 60s通话时长
100坐席容量:1.67 CAPS 60s通话时长
200坐席容量:3.33 CAPS 60s通话时长
测试过程中,修改了通话时长为30s,然后通过修改每秒呼叫量来控制并发的呼叫。实际测试50个并发,一共拨了5000个呼叫没出现问题。但是到100个并发的时候,uac发送过去的invite,由于服务器资源不够,直接回404 not found了,没有直接转给uas。
脚本如下,当然,不是全部自己写的,大部分都是套用模板,然后根据项目需求修改了一下流程:
uac.xml:原本呼叫中心是发两个invite给uac的,取消了播工号,然后注释了一次invite,只发送一次invite。
评论反馈之前的脚本不对应,估计是因为之前是直接改了就copy上来了,没有验证,现在直接从服务器copy了一份正常执行的上来,里面注释了一次invite,应该是可以执行的。
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE scenario (View Source for full doctype...)>
<scenario name="Basic Sipstone UAC">
<send retrans="1000">
<![CDATA[
INVITE sip:02099635005@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: "sipp" <sip:[field0]@[local_ip]:[local_port]>;tag=[call_number]
To: "sut"<sip:02099635005@[remote_ip]:[remote_port]>
Call-ID: [call_id]
CSeq: 1 INVITE
Contact: <sip:sipp@[local_ip]:[local_port]>
Max-Forwards: 70
Subject: Performance Test
Content-Type: application/sdp
Content-Length: [len]
v=0
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
s=-
c=IN IP[local_ip_type] [local_ip]
t=0 0
m=audio [auto_media_port] RTP/AVP 8
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-11,16
]]>
</send>
<recv response="100" optional="true" />
<recv response="180" optional="true" />
<recv response="183" optional="true" />
<!-- By adding rrs="true" (Record Route Sets), the route sets
-->
<!-- are saved and used for following messages sent. Useful to test
-->
<!-- against stateful SIP proxies/B2BUAs.
-->
<recv response="200" rtd="true" />
<!-- Packet lost can be simulated in any send/recv message by
-->
<!-- by adding the 'lost = "10"'. Value can be [1-100] percent.
-->
<send>
<![CDATA[
ACK sip:02099635005@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch];rport
From: "[field0]"<sip:[field0]@[local_ip]:[local_port]>;tag=[call_number]
To: "02099635005"<sip:02099635005@[remote_ip]:[remote_port]>[peer_tag_param]
Call-ID: [call_id]
CSeq: 1 ACK
Contact: <sip:[field0]@[local_ip]:[local_port]>
Max-Forwards: 70
Subject: Performance Test
Content-Length: 0
]]>
</send>
<!--
<recv request="INVITE" crlf="true">
</recv>
<send retrans="500">
<![CDATA[
SIP/2.0 200 OK
[last_Via:]
[last_From:]
[last_To:];tag=[call_number]
[last_Call-ID:]
[last_CSeq:]
Contact: <sip:[local_ip]:[local_port];transport=[transport]>
Max-Forwards: 70
Subject: Performance Test
Content-Type: application/sdp
Content-Length: [len]
v=0
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
s=-
c=IN IP[local_ip_type] [local_ip]
t=0 0
m=audio [auto_media_port] RTP/AVP 8
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-11,16
]]>
</send>
<recv request="ACK"
rtd="true"
crlf="true">
</recv>
<nop>
<action>
<exec play_pcap_audio="/home/roger/uac/pcap/1.pcap"/>
</action>
</nop>
-->
<!-- Pause 8 seconds, which is approximately the duration of the -->
<!-- PCAP file -->
<pause milliseconds="20000" />
<send retrans="500">
<![CDATA[
BYE sip:02099635005@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch];rport
From: "[field0]"<sip:[field0]@[local_ip]:[local_port]>;tag=[call_number]
To: "02099635005"<sip:02099635005@[remote_ip]:[remote_port]>[peer_tag_param]
Call-ID: [call_id]
CSeq: 2 BYE
Contact: <sip:[field0]@[local_ip]:[local_port]>
Max-Forwards: 70
Subject: Performance Test
Content-Length: 0
]]>
</send>
<recv response="200" crlf="true" />
<!-- definition of the response time repartition table (unit is ms)
-->
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200" />
<!-- definition of the call length repartition table (unit is ms)
-->
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000" />
</scenario>
uas.xml:这个配置的流程,也就根据uac.xml来修改,需要对应请求和响应,基本上启动了就不怎么管了。
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">
<!-- This program is free software; you can redistribute it and/or -->
<!-- modify it under the terms of the GNU General Public License as -->
<!-- published by the Free Software Foundation; either version 2 of the -->
<!-- License, or (at your option) any later version. -->
<!-- -->
<!-- This program is distributed in the hope that it will be useful, -->
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
<!-- GNU General Public License for more details. -->
<!-- -->
<!-- You should have received a copy of the GNU General Public License -->
<!-- along with this program; if not, write to the -->
<!-- Free Software Foundation, Inc., -->
<!-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->
<!-- -->
<!-- Sipp default 'uas' scenario. -->
<!-- -->
<scenario name="Basic UAS responder">
<!-- By adding rrs="true" (Record Route Sets), the route sets -->
<!-- are saved and used for following messages sent. Useful to test -->
<!-- against stateful SIP proxies/B2BUAs. -->
<recv request="INVITE" crlf="true">
</recv>
<!-- The '[last_*]' keyword is replaced automatically by the -->
<!-- specified header if it was present in the last message received -->
<!-- (except if it was a retransmission). If the header was not -->
<!-- present or if no message has been received, the '[last_*]' -->
<!-- keyword is discarded, and all bytes until the end of the line -->
<!-- are also discarded. -->
<!-- -->
<!-- If the specified header was present several times in the -->
<!-- message, all occurences are concatenated (CRLF seperated) -->
<!-- to be used in place of the '[last_*]' keyword. -->
<send>
<![CDATA[
SIP/2.0 180 Ringing
[last_Via:]
[last_From:]
[last_To:];tag=[call_number]
[last_Call-ID:]
[last_CSeq:]
Contact: <sip:[local_ip]:[local_port];transport=[transport]>
Content-Length: 0
]]>
</send>
<send retrans="500">
<![CDATA[
SIP/2.0 200 OK
[last_Via:]
[last_From:]
[last_To:];tag=[call_number]
[last_Call-ID:]
[last_CSeq:]
Contact: <sip:[local_ip]:[local_port];transport=[transport]>
Max-Forwards: 70
Subject: Performance Test
Content-Type: application/sdp
Content-Length: [len]
v=0
o=user2 53655765 2353687637 IN IP[local_ip_type] [local_ip]
s=-sipp
c=IN IP[local_ip_type] [local_ip]
t=0 0
m=audio 22222 RTP/AVP 8
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-11,16
]]>
</send>
<recv request="ACK"
rtd="true"
crlf="true">
</recv>
<!--<pause milliseconds="20000" /> -->
<recv request="BYE">
</recv>
<send>
<![CDATA[
SIP/2.0 200 OK
[last_Via:]
[last_From:]
[last_To:]
[last_Call-ID:]
[last_CSeq:]
Contact: <sip:[local_ip]:[local_port];transport=[transport]>
Content-Length: 0
]]>
</send>
<!-- Keep the call open for a while in case the 200 is lost to be -->
<!-- able to retransmit it if we receive the BYE again. -->
<pause milliseconds="500"/>
<!-- definition of the response time repartition table (unit is ms) -->
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
<!-- definition of the call length repartition table (unit is ms) -->
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
</scenario>
执行脚本,需要用以下格式添加csv的文件,作为uac侧发起呼叫的号码资源或者用随机号码。
uac1.csv,指定手机号
uac2.csv:随机手机号
--------------------------------------------------------------------分割---------------------------------------------------------------------------------
10.32.121.20---安装sipp的服务器地址
10.32.121.11:7896---sip服务器地址
uas侧命令如下(需要先启动uas,不然uac启动了没对应的接收请求端了):
./sipp -sn uas -i 10.32.121.20 -p 5777 -sf /perf/sipp-script/uas.xml
说明:作为uas启动,5666为本地监听uac端的端口。
uac侧命令如下:
./sipp -sn uac 10.32.121.11:7896 -i 10.32.121.20 -p 5666 -m 500 -l 50 -r 3 -rp 1000 -sf /perf/sipp-script/uac.xml -inf /perf/sipp-script/uac.csv -trace_msg
说明:作为uac启动,每秒一个访客呼入客服,呼叫500次后停止,最大同时并发50个,5666为本地监听uac端的端口;uac.csv 这个文件路径是前面用csv格式保存的uac读取的号码资源文件。
命令参数说明:
-sn uc:作为客户端执行
-sn us:作为服务端执行
172.16.71.21:5060--对方IP
-i: 本地ip
-p:本地端口
-m:发送N次呼叫后停止并退出
-l: 最大同时通话数量,表示最大并发数,即同时可接电话的坐席数量
-r 1 -rp 1000: 每秒发送一个呼叫
-sf: 场景文件路径:
-inf:CSV文件路径