如何提高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;
相關文章
相關標籤/搜索