您现在的位置是:首页 > 文章详情

如何提升Asterisk 执行脚本的性能

日期:2020-04-04点击:498
 我们在做Asterisk功能开发的时候,除了直接用C写模块之前,更常用的方法是用自己熟悉的语言来开发自己的业务逻辑,这个时候就需要用到AGI的功能。一般比较多的选择是:PHP,Perl,JAVA 来实现。JAVA因为是FASTAGI的方式,故效果会比PHP,Perl好点,因为PHP,Perl是脚本语音,需要进行编译操作,故这个CPU消耗还是比较大的。 另外一种方式是asterisk 的dialplan 是可以直接支持lua 脚本来编写,这个就很方便来用lua 来做扩展。经过实测使用Lua方式来做嵌入式来扩展业务,这个性能确实有质的飞跃。 故本次将介绍使用Lua来写dialPlan。 官方文档指引,请参考: https://wiki.asterisk.org/wiki/display/AST/Lua+Dialplan+Configuration 通过官方文档的介绍,其实extensions.lua 其实就是一个lua 脚本,直接在上面写代码即可。 关于数据存储的选择技巧: 如果要快速响应呼叫请求,可以利用redis 来做缓存,使用redis 的列表功能进行消息推送。把话单和通话状态通过外部的监控服务来推送到MySQL。 经过上面的改造后,Asterisk的性能得到了很大的提升,下面是具体的测试效果: CPU型号: Intel(R) Core(TM) i3-4020Y CPU @ 1.50GHz CPU个数:4 内存:4G Asterisk版本:Asterisk 13.21.0 上面安装了2套Asterisk,一套做接入转码,一套做模拟正常的30%的接通率。 稳定并发:150线并发 一台微型小机器,即可满足大部分公司的业务需求。 下面附上lua dialplan 的使用例子:
function hangup() app.Hangup() end function verbose(msg) app.Verbose('"' .. msg .. '"') end function noop(msg) app.Noop('"' .. msg .. '"') end function dial(dialstr) app.Dial(dialstr) end function getChannelItem(item) return channel.CHANNEL('"' .. item .. '"'):get() end function getCallerIdItem(item) return channel.CALLERID('"' .. item .. '"'):get() end function getVar(key) -- key : CALLERID(num) ,EXTEN , CHANNEL return channel[key]:get(); end function setVar(key,val) channel[key] = val; end e = {}; e.default = {}; e.default["_X."] = function(context,exten) app.Noop("incoming call to default") app.Hangup() end; e.TO_EXT_UserName = {}; e.TO_EXT_UserName["_X."] = function(context,exten) local peerIp = channel.CHANNEL('peerip'):get() local userAgent = channel.CHANNEL('useragent'):get() local uriHeader = channel.CHANNEL('ruri'):get() local from = channel.CHANNEL('from'):get() local concat = getChannelItem('uri') local caller = getCallerIdItem('num'); local callerName = getCallerIdItem('name') local uniqueid = getVar('UNIQUEID'); local channelName = getVar('CHANNEL'); setVar('CALLERID(num)','+8615875329063') local msg = 'incoming call: ' .. peerIp .. ',useragent: '.. userAgent .. ',request uri: ' .. uriHeader ..',from header: ' .. from .. ',concat header: ' .. concat ; verbose(msg); msg = "caller: " .. caller ..",callerName: " .. callerName ..',uniqueid: ' .. uniqueid .. ',channel name: ' .. channelName; noop(msg); caller = getVar('CALLERID(num)'); noop("Your new callerid is: " .. caller) local res = dial("SIP/IMS_PROXY/" .. exten .. ',45,geU(sub_record_ims^s)') hangup() end; e.TO_EXT_UserName["h"] = function(context,exten) local msg = ''; local caller = getCallerIdItem('num'); local callerName = getCallerIdItem('name') local uniqueid = getVar('UNIQUEID'); local duration = getVar('DIALEDTIME'); if duration == nil or duration == '' then duration = 0; end local billsec = getVar('ANSWEREDTIME'); if billsec == nil or billsec == '' then billsec = 0; end local dialresult = getVar('DIALSTATUS'); if dialresult == nil then dialresult = '' end -- 获取挂断通道名称 local hangupCauseString = getVar('HANGUPCAUSE_KEYS()'); msg = "hangup==> caller: " .. caller .. ',is hangup,uniqueid='.. uniqueid .. ',duration='.. duration .. ',billsec='.. billsec .. ',result: ' .. dialresult; noop(msg) -- 获取挂断原因SIP代码 local hangupCause = getVar('HANGUPCAUSE("' .. hangupCauseString ..'",tech)'); msg = "hangup by: " .. hangupCauseString .. ',hangupCause: ' .. hangupCause; noop(msg) end; e.sub_record_ims = {}; e.sub_record_ims['s'] = function(context,exten) -- 当被叫接通主叫前执行 local msg = ""; local caller = getCallerIdItem('num'); local callerName = getCallerIdItem('name') local uniqueId = getVar('UNIQUEID'); msg = "caller: " .. caller .. ',callerName: ' .. callerName .. ',uniqueId: ' .. uniqueId .. ' is answered ...'; noop(msg); app['Return'](); end extensions = e;
原文链接:https://blog.51cto.com/carryf/2484867
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章