一、背景:
关于homer的功能、作用和如何部署,大家网上都可以找到详细的介绍,本次主要说一下部署homer之后,遇到的一个bug处理。相信大家日常管理freeswitch的时候,如果不细心关注的话,基本不会发现有这个bug。
二、homer作用:
有如下亮点:
1、可以为大型的呼叫中心实现一套统一的sip抓包平台,服务端本身也支持docker部署,所以部署起来还是比较方便的。
2、而像freeswitch作为客户端只需配置几个参数就可以直接对接到homer服务器,也是非常方便的。
3、对于其他呼叫平台,底层不支持的也可以通过sngrep作为客户端连接到homer(本人只在测试环境asterisk上面使用,没有在线上大量使用验证可靠性)
三、homer服务端部署:
1、参照官网docker部署,暂时不做详细展开
四、在freeswitch上面启用capture:
#1、在sofia.conf.xml中,启用homer的服务端地址:
<param name="capture-server" value="udp:xxx.xxx.xxx.xxx:9060;hep=3;capture_id=88"/>
#2、分别在internal.xml和external.xml文件中,启用capture:
#启用方式,将sip-capture的默认参数no,改为yes即可
<param name="sip-capture" value="yes"/>
#3、重启freeswitch:
做完以上操作,即完成freeswitch对接homer的所有设置,就是这么简单,不出意外的话,就大功告成。
五、全局开关freeswitch的capture:
#freeswitch很人性化,提供了全局一键开关capture
#全局关闭capture:
fs_cli -x 'sofia global capture off'
#全局打开capture:
fs_cli -x 'sofia global capture on'
六、freeswitch启用capture bug复现
做了以上操作,启用freeswitch的capture之后,登录homer管理平台,就可以在homer平台上面看到freeswitch的每通电话sip呼叫信令信息了,对于故障排查就比较方便了,结合freeswitch的log是一个很好的补充。
1、在freeswitch使用capture过程中,偶然查看log,发现总有一些如下的偶发错误,数量不多,但是每天总有一些:
[ERR] switch_core_media.c:9648 AUDIO RTP REPORTS ERROR: [Bind Error! xx.xx.xx.xx:33520]
[WARNING] mod_sofia.c:2588 CODEC NEGOTIATION ERROR. SDP:
2、一开始以为是一些偶发的通话异常,也并没有当回事,数量也不多,就认为是个别的线路造成的异常,直到某一天偶然的发现好像启用了capture的freeswitch上面都有这个情况,本人刚好是在freeswitch并发非常大的机器上面启用了capture抓包功能。
3、在发现了每台启用了capture抓包功能的freeswitch上面都有这个情况的时候,我才意识到这个可能是哪里有点问题。细看log之下,终于发现了另外一个更具代表性的异常。
#出现该错误的时候,一开始容易忽略,以为是个别的通话异常,其实是可以理解的,直到发现每次出现这个异常的时候,ip后面的端口都是一样的时候,才终于发现这不是个别的通话异常,不会每次通话异常的时候,freeswitch都用这个rtp端口的嘛
[ERR] switch_core_media.c:9648 AUDIO RTP REPORTS ERROR: [Bind Error! xx.xx.xx.xx:33520]
4、那么这个异常的rtp端口是有什么特殊性么?
通过netstat查看一下,发现了该端口的连接是连到了homer的服务端,也就是这个是freeswitch和homer通讯的时候,使用的端口,而freeswitch在通话过程中,分配rtp端口的时候,当分到这个端口的时候,发现这个端口已经在使用中了,于是造成了通话异常,这个才是造成总有部分通话异常的根本原因了。
5、为什么freeswitch在分配rtp端口的时候,会和连接homer的端口重复呢?
这个也好理解了,freeswitch在启动的时候,rtp端口范围是写在switch.conf.xml文件当中的,
freeswitch在启动后,capture功能是随着freeswitch一起启动的,capture连接到homer的时候,会随机占用2个udp端口;而freeswitch启用的时候,默认占用的是5060和5080等udp端口,
rtp范围端口是不占用的,是每次打电话的时候,有需要rtp端口的时候freeswitch才进行分配的,分配的时候发现端口被占用了,才会报错。
6、那么如何解决这个问题呢?
知道问题原因了,那么解决办法也就有了,根本原因是capture启动的时候,随机生成的udp端口,刚好在freeswitch使用的rtp端口范围内,当freeswitch要使用这个端口的时候,发现使用不了,就会导致该通通话异常。
1、那么不让capture使用的udp端口在freeswitch的rtp端口范围内是不是就能解决问题呢?
2、即便capture使用了rtp端口范围内的端口了,那么freeswitch每次分配rtp端口的时候,能不能检测一下呢?如果端口已经在使用了,就不分配该端口,分配别的端口行不行呢?
以上2个思路,应该是都可以解决上面的capture端口占用问题的,其实不单单是capture会占用端口,如果你在部署了freeswitch的机器上面,还部署了很多需要使用udp端口通讯的服务的时候,都有可能会占用到了freeswitch的rtp端口,毕竟rtp端口是一个很大的范围。
七、解决方案:
方案1:
既然capture占用了freeswitch的rtp端口范围里面的端口,那能不能设置capture不占用rtp端口范围里面的端口呢?查看设置capture的相关配置,发现sofia.conf.xml文件里面,只规定了homer服务端的地址和端口,并不能设置作为客户端使用的端口,客户端的端口是服务启动的时候,随机生成的。随机生成的?
#比较粗暴的方案:
1、既然是随机生成的,那就通过全局启用和关闭capture吧,通过全局启动capture之后,观察capture的端口是不是在rtp端口范围外,如果不是则关闭capture,重新启动;直到端口范围在rtp端口范围外即可
#全局关闭capture:
fs_cli -x 'sofia global capture on'
#netstat -an |grep ':9060'
#全局打开capture:
fs_cli -x 'sofia global capture on'
注意事项:
该方案能解决问题,只要freeswitch和capture服务不出问题,这样做是没有问题的;不过当freeswitch或capture需要重启的时候,就需要重新关注端口范围了,有点傻,但是见效也快。
方案2:
怎么让freeswitch每次分配rtp端口的时候,检查一下端口是否在使用呢?查找freeswitch相关的配置,发现freeswitch自身还真就支持该功能,在switch.conf.xml里面有一个rtp-port-usage-robustness参数可以配置:
#在switch.conf.xml里面,启用如下参数即可在每次分配rtp端口的时候,先检测端口是否在使用,避免分配了已经在使用中的端口,该功能默认是不启用的
<param name="rtp-port-usage-robustness" value="true"/>
注意事项:
该方案也能解决问题,相比方案1更具有优越性,如果没有特殊原因的话,可以尝试该方案的,
如果说有什么缺点的话,该方案相比方案1可能会增加一点性能开销吧。
更多讨论可加QQ群:482489124