由于工作的原因,需要对osip协议栈进行优化,前段时间在论坛上看到lw3223兄对于osip协议栈hash查找事务的讨论,鉴于此把自己这段时间对osip的优化和心得总结出来大家共享一下。写的比较匆忙,有点乱,大家见谅了。
众所周知,Osip协议栈是用C语言编写,实现了SIP协议基于事务层的处理,后来作者对协议栈进行了扩展,提供了call级的操作处理,也就是eXosip。Osip小巧,灵活,易扩展,比较方便用来实现UA,但是用作proxy的话性能上有点满足不了需求(听说有个改良版的partysip,没用过,我们这里只讨论osip的优化),有必要对其进行优化一番。
这里使用的是最新3.0.1的版本,有些固有的影响性能的因素,比如消息的解析,复制,转换到字符串以及释放等暂不予讨论,大家有什么好的方案也可以一起讨论一下。我们可以围绕协议栈线程主执行函数_eXosip_execute()来展开对它的优化工作。
1.1 SIP Message到transaction的映射
Osip性能低下的一个重要原因便是有太多的for循环,尤其是在事务层SIP消息到事务的匹配,好在osip预留了hash的处理方法,为我们的优化节省了不少的工作量。打开编译宏HE_DICT_DICT_H,协议栈便会使用libdict库对四种事务进行hash的插入,查找,删除等。如果您手头有这个库,到这里这一步就可以完成了。由于这个库不是linux自带的,你可能需要自己给协议栈实现一个hash算法,增加osip_hash.c和osip_hash.h两个文件基本上就OK了。
经过测试,这项操作对性能的提升约1/10左右。由于测试的压力较小,因此查询效率的提升不是很明显,但是当呼叫量和并发数较大时,对性能的改善应该会比较明显。
1.2 Osip状态机的处理效率
协议栈处理事务事件(这里指osip事件,非eXosip事件)的主函数是osip_xxx_execute(),在这里xxx分别代表osip的四种状态机ict, ist, nict, nist,以下如未经特别说明均使用该准则。
随便捡一个来看,比如osip_ist_execute()函数,你会发现这个函数也就是轮询事务列表,找到有事件需要处理的事务,然后调用每个状态下对不同事件的状态机处理函数fsm,仅此而已。重点就在轮询,至于它是怎么调用到具体的fsm,稍后再讨论。你可以想象一下,每秒100calls的呼叫率,每个call的接续时间为10秒,那么ist事务列表的长度便是1000。你可以认为循环1000次没什么,但是你要想想主执行函数_eXosip_execute()的调用频率(其实是一直阻塞于该函数中)是非常高的,只要有SIP消息的来往就会产生相应的SIP事件来唤醒协议栈。
经过实际测试,在nict事务列表平均长度为4xx时,平均不到一个事务需要处理事件,可见四个状态机的执行函数osip_xxx_execute()就不能执行太多的无用操作,所以这里有必要提高轮询事务的效率。
最简单的方法就是在osip_t结构体里增加四个活动的事务列表osip_xxx_active_transactions,分别对应四个状态机,只存放有事件需要处理的事务,为了不影响到原来的协议栈,也方便以后的调试,所有关于状态机的优化都加上编译宏OSIP_FSM_OPTIMIZE。这样四个状态机的执行函数osip_xxx_execute()就只需要轮询活动事务列表即可。
需要作出修改的函数如下:
__osip_add_xxx(),
__osip_remove_xxx_transaction(), /* 可能不需要修改 */
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/tongxinshuyu/article-38863-1.html
因此广得民心
你这不是自己在打自己的脸吗