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

咱们在作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;
相关文章
相关标签/搜索