🏠 作 者:小小马车夫
🍅 所属专栏:【FreeSwitch开发实践】
🥝 专栏介绍:主要介绍博主在实际项目中使用FreeSwitch开发外呼类项目的一些经验心得,主要涉及FreeSwitch的基本安装编译、基本配置、ESL、WSS、录音、自定义模块、media bug、语音播放、MRCP及对接AI机器人等内容。内容在持续更新中,如果感兴趣可以对专栏进行订阅~
🍒 个人警醒与诸君共勉:间歇性的努力和蒙混过日子,都是对之前努力的清零。
系列文章目录
【FreeSwitch开发实践】centos7下编译安装freeswitch及常见编译问题的解决
【FreeSwitch开发实践】freeswitch配置wss
【FreeSwitch开发实践】freeswitch配置wss证书问题 Encrypted Alert/Certification Unknown
【FreeSwitch开发实践】ESL简介
【FreeSwitch开发实践】ESL配置
【FreeSwitch开发实践】在nodejs中用ESL连接FreeSwitch
文章目录
前言
今天介绍一个博主项目中遇到的问题, 当日系统外呼数达到1000之后,后续外呼无法再成功,查看FreeSwitch日志发现有如下错误:
2022-07-14 13:51:36.101122 100.00% [DEBUG] switch_ivr_originate.c:2281 Parsing global variables
2022-07-14 13:51:36.101122 100.00% [CRIT] switch_core_session.c:2432 Over Session Limit! 1000
2022-07-14 13:51:36.101122 100.00% [CRIT] mod_sofia.c:4762 Error Creating Session
2022-07-14 13:51:36.101122 100.00% [NOTICE] switch_ivr_originate.c:3039 Cannot create outgoing channel of type [sofia] cause: [DESTINATION_OUT_OF_ORDER]
从日志上看Over Session Limit! 1000
即有错误信息,就好办了,顺藤摸瓜查就是了。
环境简介:
系统: CentOS7.6 64位
FreeSwitch版本: 1.10.7
一、第一处错误:Over Session Limit! 1000
这一处理错误日志是在源码
switch_core_session.c switch_core_session_request_uuid
函数中,大致看下,可知此函数功能是创建会话session进获取uuid。
这里
session_manager.session_limit
值是1000,意思是呼叫的最大值, 它是在配置switch.conf.xml
中配置的,如下:
看到这里,第一反应
呼叫
达到最大限制
, 但是项目中并发并没有1000这么高,那就继续查吧。
二、第二处错误:Locked, Waiting on external entities
查到这里基本是用的对比的方法, 对比线上环境打的手机号码,和线下测试环境打的软电话:
1 线上环境打的手机号码
2 线下测试环境的打的软电话
先看下日志上的区别:
区别就是线上没有中间
蓝色
字体的日志, 说明在打印Locked, Waiting on external entities
之后卡住了
! 离问题原因更进一步了,接着在看Locked, Waiting on external entities
打印,源码位置:
switch_core_session.c
switch_core_session_thread
可以看到在
switch_core_session_write_lock
这一行之后就卡住了, 这个函数是加锁的, 说明在之前某些地方加锁了没有释放,造成这里死锁
了。
三、github buglist的一些答案
从第二章看
switch_core_session_write_lock
函数加锁为线索,找加锁的地方,发现还是非常多的,貌似不是顷刻间能有发现的,先google一下,看看是不是有前人已经遇到过这类问题了。发现还真有:
https://github.com/signalwire/freeswitch/issues/960
从中看到确实有好多人遇到过这个问题,解决办法如下:
但是我所用的
FreeSwitch
版本1.10.7
已经有了这些修改!所以这并不能解决我遇到的问题,还是按第二章的思路继续查吧。
相关修改 switch_ivr_originate.c对应位置的代码:
四、问题定位:switch_core_session_force_locate
这里着重查加锁的地方,全工程查一下都在哪里用到了加锁,逐个排查看哪里没有释放。最后还是定位到一个接口:
switch_core_session_force_locate
switch_core.h
switch_core_session.c
这个函数在返回成功的时候调用了
switch_thread_rwlock_tryrdlock
函数来加锁, 但没有释放,而恰好项目确实用到了这个函数。那么问题基本定位了,所有用到了switch_core_session_force_locate
的函数,用完获取到的session
之后要解锁,如下:
switch_core_session_t *session;
if ((session = switch_core_session_force_locate(uuid))) {
//do_something
switch_core_session_rwunlock(session);
}
总结
以上就是今天的内容,通过日志寻找线索,最后顺藤摸瓜解决Locked, Waiting on external entities
问题的过程。
如果觉得有些帮助或觉得文章还不错,请关注一下博主,您的关注是我持续写作的动力。另外,如果有什么问题,可以在评论区留言,或者私信博主,博主看到后会第一时间回复。