首页 > 其他分享 >记最近一次紧张的sip客户端问题排查

记最近一次紧张的sip客户端问题排查

时间:2024-07-28 11:18:35浏览次数:14  
标签:sip 问题 排查 版本 日志 linphone 呼叫 客户端

我司开发了一个sip软电话客户端(sip协议常用于网络音视频通讯),基于开源的linphone sdk,使用C# CPF框架开发,.netcore运行时。有windows版本和uos版本。windows版本之前说是要支持视频,CPF里面支持视频只找到一个办法,就是NativeElement控件使用winform的pictureBox来显示,只能用4.x版本的linphone sdk。4.5.26是4.x系列的最后版本,大概2021年的,所以就用它了。集成sdk开发好后,其实没有做充分的压测,只测试了一通长呼叫保持几十小时的情况,没有测大量反复短呼叫的情况。一方面是没有开发相关的压测工具,一方面也过于信任linphone的可靠性,呼了十来通没问题就以为不会出现问题了。现场是win7的系统,上线使用后,时不时发生程序宕机、坐席听不到客户声音的情况。

宕机的问题一开始看日志没有找到准确的原因,后来查看windows系统日志,发现有.net runtime的报错,错误码多是0xc00000005,原因描述是access violation,内存非法访问。配置windows注册表错误报告功能,宕机时将内存dump转储出来dmp文件,配合官方sdk中的pdb文件用windbg分析,都是各式各样的linphone内部异常。

坐席听不到客户声音的问题,发现有出现音频设备接口初始化失败的linphone日志,一开始怀疑是耳机硬件问题。运维说,不太可能,因为不是一直有问题,有时候一通出现问题,下一通又好了。我说,可能耳机短暂接触不良呢。后来发现日志中带有一个错误码88890017,网上一查,是AUDCLNT_E_CPUUSAGE_EXCEEDED,CPU占用率过高。

由于都是linphone内部问题,我们考虑升级linphone sdk版本到5.2.114,或许新版linphone能解决宕机的问题。正好项目上不用sip视频了,所以就升级sdk版本了。另外听不到客户声音的问题,公司有个技术大佬后来开发了一个压测工具,可以对sip发起反复呼叫。压测发现呼叫180多通后必现,跟win7的audiodg.exe进程有关,反复呼叫时这个进程内存一直在缓慢增长,一开始10MB,达到40MB左右时就会报音频设备接口初始化失败的错误。所以做了一个呼叫达到100次自动重启系统音频服务的功能。经过8小时1000多次呼叫压测是正常的,没有再报错。

这是之前的基本情况。

然后客户升级了。升级后,大量出现客户听不到坐席声音的问题。之前是坐席听不到客户声音。一看日志,有一个日志报了个录音设备没有录音能力的错误,更多的日志报的是打开文件失败。我们有的怀疑是麦克风硬件问题,有的怀疑是网络问题。后来禁用麦克风测试,日志出现类似的情况,就主要怀疑是麦克风硬件问题了。打开文件失败怀疑是打开设备文件描述符失败。

然后我们说要测试下麦克风的兼容性,于是我就出差去现场了。到现场拿到耳机进行反复初始化,反复呼叫测试,并没有重现问题。

这时客户报的问题越来越多,一天20多例。我就有点懵逼了。难道是升级导致的?linphone新版或者重启音频服务的功能导致了这个问题?如果是这样问题就是我的责任了。感觉很捉急,压力很大。

这时我们公司的另一个技术大佬出场了。开发总监说技术大佬很厉害,让我找他帮忙看看。之前只找他看了音频设备初始化失败的问题,这时他分析了linphone代码,给出了修改linphone源码的建议。我一脸懵逼,不知道怎么修改。但是我把客户听不到坐席声音的问题也发给他看了。

大佬一看,这就是个打开普通音频文件没有找到文件。过了一会大佬指出sip信令里面有个sendonly,表示媒体协商成了单通。这个原因一找到,事情就解决大半了。不是麦克风硬件有问题,也不是打不开设备文件,而是单通的时候linphone尝试像呼叫保持一样播放一个音乐文件,没有找到那个文件而已。

后续沿这个方向排查,查历史日志,在sip客户端升级前就出现过这个问题了。最后确定问题出在sip网关底层,跟2个月前上线的呼叫保持功能有关系。

从周一到周五排查问题期间是非常紧张的。因为原计划周六进行割接,如果问题不解决,就割接不了,会导致严重的后果。好在最终在周五上午定位并重现了问题。

经过这次排查过程,我充分认识到了自己的技术能力不足,对公司大佬更加佩服了。有的能力不是看书能够学到的,要在实际场景中随机应变,跳出思维定式,需要有充分的实践经验才行。比如sip通信中的sendonly协商,这些书上也不会讲,即使讲了一般也注意不到,遇到一端听不到另一端声音的情况时我也想不到这一点。要不是大佬指点,可能再查两天也找不到原因。

----------------两天后----------------

一波未平,一波又起。周六晚上,割接前,又报了几个sip客户端坐席无声的问题。分析原因是很多呼叫中,会进行IVR验密操作,一次验密会多发两个INVITE事件,导致不到100通呼叫就会出现100多次INVITE,每次INVITE都会触发初始化音频设备的接口调用。接口调用这里可能有内存资源没有释放,导致最终内存不足报错。因为次数计算的差异,也没有能够在报错前自动重启系统音频服务。

甲方还比较讲情理,没有因此停止割接。于是周六晚上上线了1000坐席。周日上午都还正常,到中午13点半就开始出现音频设备初始化失败的问题(Could not initialize the MSWASAPI audio output interface [88890017],有时是8007000e错误码)。下午该问题越来越多,数量惊人。我们紧急修改了几个版本,40通呼叫就重启系统音频服务,以及别的一些逻辑和问题修改。但是这都是治标不治本的办法,还得想办法解决音频内存资源没有释放的问题。

linphone sdk的源码我去年尝试编译过没有成功。这次又重新拿起新版本尝试编译。没想到5.2.114新版本编译步骤自动化了很多,很多库都是自动安装的。结果尝试了一天编译成功了。又请教大佬帮忙看linphone mswasapi模块源码。大佬让我加一些日志运行给他看看。一开始编译后的libmswasapi.dll在win7下不能加载,后来发现编译成debug的dll了,依赖的库是vc redistibutable的debug库。修改成RelWithDebInfo后编译出来的dll能够加载了。大佬看了日志后,找到了内存泄露的地方。

点击查看代码
mswasapi_write.cpp有个bug:
result = mAudioClient->GetService(IID_ISimpleAudioVolume, (void **)&mVolumeControler);  //mVolumeControler没有释放。

int MSWASAPIWriter::deactivate()
{
	ms_message("MSWASAPIWriter::deactivate()");
	RELEASE_CLIENT(mAudioRenderClient);
            。。。增加释放mVolumeControler
	mIsActivated = false;
	return 0;
}

这个问题3年前的4.5.26版本就存在,估计更早的4.x版本也有,一直到今年6月17日的5.2.114版本都没有人发现和解决。win7下呼叫100多次就必现无声的问题,居然3年一直没有人提出来有木有!我们排查了半年多啊有木有!

修改源码后重新编译,再一测试,问题解决了!audiodg.exe内存没有增长了。呼叫1000通都没有增长!

当然事情并不是完全结束了。后续还有一些问题需要解决,比如程序宕机问题,不发心跳问题。

----------------数天后----------------
5.2.114版本linphone通话中拔插耳机崩溃的问题也通过修改mswasapi模块源码解决了。
来电振铃客户放弃和坐席接听时间非常接近导致程序崩溃的问题查了几天,可能也通过修改liblinphone源码解决了,需要进一步测试稳定性。
还剩下一个偶现的不发心跳、不处理sip信令的问题,怀疑也跟前面的音频资源内存泄露有关,目前预期升级修复内存泄露版本后有改善。也在再下一个版本加了一些日志进行排查。
之前的重启音频服务版本也有意料之外问题,有的win7系统上重启没有自动识别到音频设备上线,只能建议升级到修复内存泄露版本了。

看似简单的一个sip客户端软件,遇到的问题多样性和排查解决难度超过了我的想象。linphone windows版本看似成熟实则存在不少问题,可能还是实际应用场景超过了官方测试的覆盖面。

标签:sip,问题,排查,版本,日志,linphone,呼叫,客户端
From: https://www.cnblogs.com/seraph-v3/p/18327993

相关文章

  • 如何解决用socket实现通讯,即使服务器与客户端链接得到客户端信息却仍报错的问题?
     以上分别是服务器和客户端的代码展示,方便后续大家对运行结果的了解 可以发现当服务器与客户端连接时,客户端的信息已经被服务器接收到了,但仍然报错。此时 可以调用shutdownOutput(),关闭输出流,使服务器端口得到-1值,从而关闭流。目的是告知服务器信息已经输出完毕。再次......
  • Starlette SessionMiddleware 将会话数据存储在服务器上还是客户端上?
    我正在开发一个无状态FastAPI应用程序。身份验证通过GoogleOAuth(openid电子邮件配置文件范围)进行处理。我正在使用Authlib,它使用SessionMiddleware(request.session)来存储临时代码和状态。现在,我想使用令牌限制对某些端点的访问。为此......
  • 编写Java,实现客户端向服务端上传文件的功能
    需求说明:实现客户端向服务端上传文件的功能当启动服务端后,运行客户端程序,系统提示客户在客户端输入上传文件的完整路径。当客户在客户端输入完成后,服务端实现文件上传实现思路:创建客户端类FileClient和服务端类FileServer在客户端类中定义uploadFile(Socketsocket)方......
  • 使用 caesar sipher 加密和解密
    我需要符合所有要求的代码,以便我可以完成从某家公司获得推荐信的任务。我需要帮助。实际上我尝试过使用人工智能,但该公司正在使用人工智能探测器,如果它发现我在人工智能的帮助下完成了任务,那么我将不会获得任何证书,并且我将被该公司禁止10年。我需要人工编写的代码。......
  • Hisiphp2.0.11的文件上传
    侵权声明本文章中的所有内容(包括但不限于文字、图像和其他媒体)仅供教育和参考目的。如果在本文章中使用了任何受版权保护的材料,我们满怀敬意地承认该内容的版权归原作者所有。如果您是版权持有人,并且认为您的作品被侵犯,请通过以下方式与我们联系:[[email protected]]。我们将在确......
  • 项目环境出现PHP 502 Bad Gateway 问题排查
    一、现象昨天运维人员被告知,在升级完客户集群环境后,访问管理页面偶尔会报502BadGateway。登录客户环境,发现只要请求分发到node2,就会报502,开始解决问题... 二、排查思路1、看到502第一时间想到的应该是php-fpm出问题了,先看下nginx日志,连接被对端关闭,说明php-fpm......
  • DevExtreme框架由于数据量太大,加载太慢,采用分页方式进行处理(基本上所有的操作都从客户
    首先我们需要引入官方的一个函数:importCustomStorefrom'devextreme/data/custom_store';我们需要通过这个函数去处理交互数据 先放个图: 上图中跟分页有关的属性分别是:1.:data-source="store",这个是存放数据源用的,需要用到我们上面的CustomStore函数,2.:remote-oper......
  • 使用 aws cdk 设置用户池客户端属性以具有读/写访问权限 - Python
    我试图根据属性给予一些自定义属性特定的读/写访问权限。我收到此错误。资源处理程序返回消息:“无效写入创建客户端时指定的属性(服务:CognitoIdentityProvider,状态代码:400,请求ID:<request_id>)”(RequestToken:<request_token>,HandlerErrorCode:InvalidRequest)任何人都可以为......
  • 生成包含 MSIP 标签的 .eml 文件
    我目前正在使用Python及其本机电子邮件包编写电子邮件生成器。我将一个Excel文件作为输入,并生成几个.eml文件作为输出。目标不是自动发送它们,而是让用户在Outlook中单独打开它们,进行一些修改并决定是否要发送。一切都工作得很好,只是用户必须为每个文件进行选择通过......
  • MFC制作MQTT(EMQX)客户端 - 开、关功能实现(附源码)
    前言全局说明MFC制作MQTT客户端(附源码)一、说明环境:Windows7旗舰版VisualStudio2013CMakeversion3.19.8paho.mqtt.cV1.3.13二、MFC功能代码:2.1引入h头文件#include"include\MQTTAsync.h"#include"include\MQTTClient.h"2.2添加连接服务器信息......