笔者所在团队由于涉及自建呼叫中心业务,而针对客服系统这类存在大量的呼叫场景来说,呼叫服务的可靠性显得尤为重要。很显然对于一个基于Sip协议的呼叫业务来说,不可能雇佣几千人同时拨打电话,而传统压测工具(Grinder、Jmeter)等也无法满足Sip协议压测的需求,那么怎么办?FreeSwitch官方文档推荐一款简单易用的压测工具--Sipp,本文简单介绍如何应用Sipp工具对七鱼FreeSwitch服务进行压测的实践。
关于Sip协议的基础本文不扩展讲了,类似于Http协议,主要是两个关键点:协议信令和状态码,如果需要从事相关测试,那么Sip协议是必须掌握的基础。
这部分没有什么难度,按照Sipp的官网上的安装步骤安装即可。 Sipp官网
平时我们在做WEB的压力测试时,会关注应用的TPS、支持的并发能力、RT、JVM等指标,当然还有一系列的硬件指标。而SIP服务器与我们平时的应用服务器会有一些差别,SIP服务器(FreeSWITCH是一种SIP服务器)会负责会话的建立及音视频数据的传输和编解码,我们知道一通电话呼叫所持续的时间,长则上百上千秒,短则只有一两秒,所以在SIP服务器的压力测试上,虽然依然存在TPS、并发能力等指标,但是与我们平时理解的概念会稍微有一些区别。
SIP压测的指标主要有两个:
CPS:Call Per Second,每秒能够处理的通话数,它代表的是每秒钟FreeSWITCH能够建立或者释放Channel的能力
Channel:FreeSWITCH本身是一个背靠背的用户代理,因此通过FreeSWITCH建立的一个呼叫,会存在多个数据链路,我们称之为Channel,比如一个单呼可能只有一个Channel,而一个双呼则有两个Channel,一个电话会议则可能有N个Channel
对于笔者的项目,主要涉及两种场景的压测,一是用户注册、二是用户外呼,我们分别来看一下测试脚本该如何实现。
一个完整的sip注册流程如下图所示:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">
<scenario name="registration">
<send retrans="500">
<![CDATA[
REGISTER sip:cc.qiyukf.com SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
Max-Forwards: 70
From: "sipp" <sip:[field0]@cc.qiyukf.com>;tag=[call_number]
To: "sipp" <sip:[field0]@cc.qiyukf.com>
Call-ID: reg///[call_id]
CSeq: 7 REGISTER
Contact: <sip:[field0]@[local_ip]:[local_port]>
Expires: 90
Content-Length: 0
User-Agent: SIPp
]]>
</send>
<recv response="100" optional="true">
</recv>
<recv response="401" auth="true" rtd="true">
</recv>
<send retrans="500">
<![CDATA[
REGISTER sip:cc.qiyukf.com SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
Max-Forwards: 70
From: "sipp" <sip:[field0]@cc.qiyukf.com>;tag=[call_number]
To: "sipp" <sip:[field0]@cc.qiyukf.com>
Call-ID: reg///[call_id]
CSeq: 8 REGISTER
Contact: <sip:[field0]@[local_ip]:[local_port]>
Expires: 90
Content-Length: 0
User-Agent: SIPp
[field1]
]]>
</send>
<recv response="100" optional="true">
</recv>
<recv response="200">
</recv>
<ResponseTimeRepartition value="10, 20"/>
<CallLengthRepartition value="10"/>
</scenario>
sipp 59.XXX.XXX.XXX:5160 -i 10.XXX.XXX.XXX -p 5050 -s 999999999 -r 1000 -inf register_data.csv -sf sipp_uac_register.xml -trace_screen
测试完成后Sipp会输出相应的呼叫次数,成功、失败次数及各种时长信息等,除此,我们还需要关注服务器CPU、内存、IO、网络指标,以及进入FreeSWITCH查看注册的正确率,以保证性能测试的可靠。
一个完整的Sip外呼流程如下图所示:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">
<scenario name="Basic Sipstone UAC">
<send retrans="500">
<![CDATA[
INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: sipp <sip:[field0]@cc.qiyukf.com>;tag=[pid]SIPpTag00[call_number]
To: sut <sip:[service]@cc.qiyukf.com>
Call-ID: [call_id]
CSeq: 1 INVITE
Contact: sip:[field0]@[local_ip]:[local_port];transport=udp
Max-Forwards: 70
Subject: Performance Test
Content-Type: application/sdp
Content-Length: [len]
v=0
o=[field0] 53655765 2353687637 IN IP4 [local_ip]
s=Talk
c=IN IP4 [local_ip]
t=0 0
m=audio [auto_media_port] rtp/avp 0 8 9 101
a=rtpmap:9 G722/8000
a=rtpmap:0 pcmu/8000
a=rtpmap:8 pcma/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-11,16
a=sendrecv
a=ptime:20
]]>
</send>
<recv response="100">
</recv>
<recv response="407" option="true" auth="true">
</recv>
<send>
<![CDATA[
ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch-3]
From: sipp <sip:[field0]@cc.qiyukf.com>;tag=[pid]SIPpTag00[call_number]
To: sut <sip:[service]@cc.qiyukf.com>[peer_tag_param]
Call-ID: [call_id]
CSeq: 1 ACK
Contact: sip:[field0]@[local_ip]:[local_port];transport=udp
Max-Forwards: 70
Subject: Performance Test
Content-Length: 0
]]>
</send>
<send retrans="500">
<![CDATA[
INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
From: sipp <sip:[field0]@cc.qiyukf.com>;tag=[pid]SIPpTag01[call_number]
To: sut <sip:[service]@cc.qiyukf.com>
Call-ID: [call_id]
CSeq: 2 INVITE
Contact: sip:[field0]@[local_ip]:[local_port];transport=udp
[field1]
Max-Forwards: 70
Subject: Performance Test
Content-Type: application/sdp
Content-Length:[len]
v=0
o=[field0] 53655765 2353687637 IN IP4 [local_ip]
s=Talk
c=IN IP4 [local_ip]
t=0 0
m=audio [auto_media_port] rtp/avp 0 8 9 101
a=rtpmap:9 G722/8000
a=rtpmap:0 pcmu/8000
a=rtpmap:8 pcma/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-11,16
a=sendrecv
a=ptime:20
]]>
</send>
<recv response="100">
</recv>
<recv response="180" optional="true">
</recv>
<recv response="183" optional="true">
</recv>
<recv response="200" rtd="true">
</recv>
<send>
<![CDATA[
ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch-5]
From: sipp <sip:[field0]@cc.qiyukf.com>;tag=[pid]SIPpTag01[call_number]
To: sut <sip:[service]@cc.qiyukf.com>[peer_tag_param]
Call-ID: [call_id]
CSeq: 2 ACK
Contact: sip:[field0]@[local_ip]:[local_port];transport=udp
[field1]
Max-Forwards: 70
Subject: Performance Test
Content-Length: 0
]]>
</send>
<nop>
<action>
<exec play_pcap_audio="g722.pcap"/>
</action>
</nop>
<pause milliseconds = "30000"/>
<send retrans="500">
<![CDATA[
BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch-7]
From: sipp <sip:[field0]@[local_ip]:[local_port]>;tag=[pid]SIPpTag01[call_number]
To: sut <sip:[service]@[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">
</recv>
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
</scenario>
UAC外呼主要模拟一个用户呼叫某个电话,电话接通后持续说话30s,之后挂断的场景,也是大部分客服经常遇到的真实场景。
sipp 59.xxx.xxx.xxx:5160 -i 10.xxx.xxx.xxx -p 5050 -s 999999999 -m 5000 -r 50 -t tn -max_socket 5000 -sf sipp_uac_basic.xml -inf qiyutest.csv -rtp_echo -trace_screen
在Sipp施压的情况下,结合服务器的硬件性能数据,可以不断的调整CPS和持续时间,来最终获取在特定硬件配置的情况下,服务器稳定运行时FreeSWITCH能够获得的最大CPS和Channel并发值。
毕竟Sip的测试对于传统Web测试来说确实属于小众,网上可借鉴资料也相对较少,笔者也是第一次接触,并且在测试过程中也是踩坑无数,特意在ks中搜索了一把,本文应该算是ks中第一篇关于Sip压测的文章,实属荣幸,同时欢迎从事相关测试的同学相互交流。
本文来自网易实践者社区,经作者李赫授权发布。