简介
Asterisk 是一个开放源代码的软件VoIP PBX系统,它是一个运行在Linux环境下的纯软件实施方案。Asterisk是一种功能非常齐全的应用程序,提供了许多电信功能,能够把你的 x86 机器变成你自己的交换机,还能够当作一台企业级的商用交换机。Asterisk让人激动的事情是它在小企业预算可承受的范围内提供了商业交换机的功能和可伸缩性。
在Asterisk的拨号方案中,可以采用各种语言很方便的通过AGI接口编写实施脚本。脚本和Asterisk之间通过标准的输入输出进行交互。具体AGI的用法就不在这里描述了。
问题描述
[sip-stdexten]
exten => _X.,1,Set(trunk=test)
exten => _X.,n,AGI(test.py,${trunk})
exten => _X.,n,dial(sip/${EXTEN}@${trunk},45)
exten => _X.,n,hangup()
上面的拨号计划,就是采用Python写的一个AGI脚本做了一些扩展应用。该段拨号计划在正常使用的情况下没有任何异常。但是在PBX的并发提高后,系统就会出现CPU负载过高、呼叫出现较大延时的情况。
load average: 83.23, 97.97, 96.79
问题分析
系统平均负载(load average)被定义为在特定时间间隔内运行队列中(在CPU上运行或者等待运行多少进程)的平均进程数。
那很明显我们的机器是在特定间隔内进程数过多,导致了进程调度不过来。那我们哪来的这么多运行的进程呢?很明显,在拨号计划执行过程中,AGI会启动进行执行脚本,每次呼叫都会执行该进程一次。当呼叫量大的时候,执行进程的数量也很大,这就导致了CPU的负载过高。
问题解决
既然用AGI调用Python脚本会导致这个问题,那么我们可以采用Asterisk 的FastAGI机制,把多进行转为单进程,这样理论上也加快了AGI的执行速度(因为Python脚本的执行,有模块动态加载等过程,使用FastAGI后每次调用就没有了这些过程)。FastAGI的实现采用pystrix,改为FastAGI后问题解决。