OpenSIPS學(xué)習(xí)筆記-dispatcher調(diào)度模塊概要-失效呼叫處理邏輯及示例演示
說明:因?yàn)槠P(guān)系,筆者不能完全介紹負(fù)載均衡模塊的全部內(nèi)容,筆者僅通過重點(diǎn)內(nèi)容和比較重點(diǎn)的問題加以說明。均衡負(fù)載的完整說明和其他筆者可能沒有涉及到參數(shù),如果讀者有興趣的話,可以參考官方的在線文檔學(xué)習(xí)。另外,筆者的示例需要OpenSIPS的控制界面來配合實(shí)現(xiàn),如果需要實(shí)際配置操作的話,讀者需要安裝OpenSIPS的配置控制界面。
具體安裝方式,請參考:
最完整快速的安裝方式安裝開源OpenSIPS-3.1和CP控制界面-class 8
在接下來的其他部分章節(jié)中,筆者將介紹負(fù)載均衡的一些基本的概念,必要的語法和負(fù)載均衡關(guān)于資源處理的說明,負(fù)載均衡中目的地選擇處理,負(fù)載均衡中選擇邏輯處理詳解,運(yùn)行環(huán)境下使用命令來實(shí)時管理和拓展系統(tǒng)資源方式,前端是OpenSIPS的電話會議中使用負(fù)載均衡的挑戰(zhàn)和解決方式,使用負(fù)載均衡模塊的配置示例演示和總結(jié)。
1負(fù)載均衡模塊的背景說明
負(fù)載均衡本身不是一個什么新鮮話題,在我們的實(shí)際生活中會經(jīng)常遇到,從單一的個體和其他資源的合作到當(dāng)前社會發(fā)展中資源整合都需要涉及負(fù)載均衡的問題。
平衡是為了更好地發(fā)展,發(fā)展是為了更好地平衡。
亞里士多德的子孫
如果具體到社會政治學(xué)的問題中,我們也可以看到負(fù)載均衡的實(shí)例。政治學(xué)之父馬基雅維利在他研究的政治學(xué)中花費(fèi)很多篇幅討論關(guān)于各種政體利弊,他非常重視各種政體中各方面勢力平衡的研究。另外,現(xiàn)代企業(yè)管理學(xué)的研究人員也都一直在探究平衡的問題。一些著名的管理學(xué)大師在討論公司運(yùn)營管理中經(jīng)常會提醒大家-“一個公司如果只有一個技術(shù)核心或者管理核心是非常危險(xiǎn)的事情。隨著公司規(guī)模的擴(kuò)大,如果沒有其他技術(shù)核心來對所謂的靈魂人物加以平衡,這樣的公司,其狀態(tài)遲早會失衡”。因此,無論是何種實(shí)體,如何在可持續(xù)發(fā)展同時能夠兼顧平衡是一個非常重要的話題。

此圖片以及以下所有圖例均來自于網(wǎng)絡(luò)資源
同樣,在我們討論的具體大規(guī)模部署的VoIP應(yīng)用環(huán)境中,負(fù)載均衡也是一個非常核心的問題。在部署企業(yè)通信應(yīng)用中,特別是在運(yùn)營層面,我們應(yīng)該首先考慮到是如何保證用戶數(shù)量增加和業(yè)務(wù)需求增加的同時,實(shí)現(xiàn)各種資源的整合和保證其基礎(chǔ)平臺的穩(wěn)定。面對這樣的挑戰(zhàn),在負(fù)載均衡時就需要要考慮增加各種資源來滿足不斷增加的需求。在OpenSIPS或者其他的商業(yè)平臺,例如FreeSBC/ProSBC,負(fù)載可以支持很多資源的負(fù)載,因此負(fù)載均衡模塊的處理,包括目的地處理是一個非常重要的話題。負(fù)載均衡可以根據(jù)遠(yuǎn)端媒體服務(wù)器的系統(tǒng)資源來決定負(fù)載均衡的策略管理,比較典型的就是一個根據(jù)QOS的處理來做負(fù)載均衡策略,或者其他業(yè)務(wù)功能的處理。

www.freesbc.cn
具體實(shí)現(xiàn)方式,參考:
語音質(zhì)量好壞誰說了算?會話邊界控制器-SBC-MOS告訴你
在OpenSIPS中,通過對LB的模塊進(jìn)行一定的配置,對目的地資源進(jìn)行查詢管理,最后再決定負(fù)載處理。這是一個相對比較非常復(fù)雜的過程,它不像調(diào)度模塊那樣,它僅對呼叫進(jìn)行調(diào)度,本身其實(shí)不關(guān)心對目的地對端的能力。但是,在負(fù)載均衡中需要根據(jù)對端能力來進(jìn)行負(fù)載的均衡處理。因此,相對于調(diào)度模塊,LB模塊需要結(jié)合對端資源進(jìn)行均衡管理。
2LB負(fù)載均衡模塊介紹
OpenSIPS的負(fù)載均衡模塊是一個非常復(fù)雜的模塊,官方對負(fù)載均衡模塊有一個非常完整的配置說明,用戶可以訪問此地址來學(xué)習(xí)。
https://opensips.org/Documentation/Tutorials-LoadBalancing-1-9
本文檔是根據(jù)官方的說明,通過自己本身的一些初淺了解,結(jié)合配置示例給用戶演示一個負(fù)載均衡的使用場景以及其他應(yīng)該注意到問題。因此,本章節(jié)以及以下章節(jié)的說明很多配置示例和官方文檔基本相同,如果用戶對完整文檔有興趣的話,可以忽略此文檔,直接參考官方文檔。這里,筆者僅重點(diǎn)強(qiáng)調(diào)幾個主要的內(nèi)容。在負(fù)載均衡模塊中,主要包括了幾個方面的內(nèi)容:
負(fù)載均衡模塊需要dialog模塊的支持。關(guān)于dialog模塊的作用,讀者可以參考?xì)v史文檔來做進(jìn)一步了解。LB模塊通過dialog模塊對呼出的呼叫進(jìn)行計(jì)數(shù)處理,記錄數(shù)據(jù)通過dialog模塊完成。如果沒有dialog模塊,LB模塊無法對對端peer進(jìn)行數(shù)據(jù)監(jiān)控。
目的地/對端peers 通過它們各自的IP地址來定義。
目的地不一定是同一類型的地址屬性,它們可以具備不同的支持能力,可以支持不同的服務(wù)和其他功能的支撐能力。
這里,讀者一定要注意目的地的類型,它們根據(jù)不同的服務(wù)或者支撐能力其定義也相對比較寬泛。因?yàn)槟康牡乜梢曰倦娫挄h能力,媒體轉(zhuǎn)換能力,呼叫落地能力等不同的能力。LB根據(jù)不同能力來提供不同的負(fù)載管理。
3負(fù)載均衡模塊的資源介紹
LB模塊的資源是目的地能力,對端peer能力的一種支持能力。例如:
一組媒體服務(wù)器支持不同的呼叫服務(wù)類型
每個服務(wù)器可能提供不同服務(wù)的組合:
- 編碼轉(zhuǎn)換功能,通過媒體服務(wù)器能力實(shí)現(xiàn)編碼轉(zhuǎn)換,例如G.729 轉(zhuǎn)G.711落地。
- 提供語音郵箱服務(wù),媒體服務(wù)器可以對呼叫支持語音郵箱的轉(zhuǎn)接功能,漏接電話轉(zhuǎn)語音郵箱。用戶稍晚時間再訪問媒體服務(wù)器的郵箱獲取對方語音留言
- 媒體服務(wù)器提供電話會議,實(shí)現(xiàn)各種會議室功能
- 語音播報(bào)功能,語音IVR服務(wù),智能客服功能
- 媒體服務(wù)器通過PSTN落地,呼叫運(yùn)營商PSTN
其實(shí),以上媒體服務(wù)器提供的服務(wù)相對其他呼叫服務(wù)來說,都比較媒體服務(wù)器消耗資源,還有一些是受落地PSTN資源的影響或者限制。媒體服務(wù)器通過各種服務(wù)的組合來實(shí)現(xiàn)目的地負(fù)載平衡處理。在實(shí)際使用場景中,編碼轉(zhuǎn)換是媒體服務(wù)器負(fù)載相當(dāng)大的一種服務(wù),同時需要花費(fèi)大量的CPU資源,無論通過軟件編碼轉(zhuǎn)換還是通過硬件編碼卡實(shí)現(xiàn)轉(zhuǎn)換,都需要增加媒體服務(wù)器的部署成本。
研究人員-Varun C針對G.711轉(zhuǎn)G.729編碼的論文中完整介紹了其通過芯片支持的處理流程。讀者有興趣的話,可以參考其發(fā)表的論文:
Transcoding of Voice Codecs G.711 to G.729 and Vice-versa Implementation on FPGA
Varun C
具體實(shí)踐中,通過開源媒體服務(wù)器實(shí)現(xiàn)Asterisk/FreeSWITCH的基于編碼卡的編碼能力支持。


另外,如果VMware通過虛擬化方式根據(jù)編碼轉(zhuǎn)換以后對語音質(zhì)量的測試也非常有價(jià)值,其技術(shù)論文是:
Voice over IP (VoIP) Performance Evaluation on VMware vSphere 5
VMware

VMware平臺針對編碼轉(zhuǎn)換和CPU相互關(guān)系的測試
因?yàn)槊襟w服務(wù)器的編碼轉(zhuǎn)換能力根據(jù)編碼支持的不同,需要OpenSIPS提前對呼叫進(jìn)行負(fù)載均衡處理,路由到另外一個媒體服務(wù)器。如果一些用戶僅僅是語音呼叫,不做編碼處理的,可以通過LB模塊路由到無需編碼處理的媒體服務(wù)器。媒體服務(wù)器的能力狀態(tài)會實(shí)時上報(bào)到前端OpenSIPS。
4負(fù)載均衡的目的地
通過以上介紹,我們簡單了解了媒體服務(wù)器的資源的限制問題。因此,在目的地組設(shè)置中就可能需要多種目的地的混合。通過LB組對各種負(fù)載均衡的場景進(jìn)行路由管理。例如:
- 呼出和呼入LB模塊的混合路由方式
- 通過0組包含所有呼入的PBX
- 過呼叫1組包含所有呼出的網(wǎng)關(guān)的路由組等方式
LB目的地組可以包括各種變化的組合,例如,在每個目的地組中可以定義提供不同的資源服務(wù),對每個資源進(jìn)行最大能力支持和最大負(fù)載, 通過SIP URL定義呼叫目的地和通過分組設(shè)置呼叫屬性。負(fù)載均衡模塊的目的地組可以設(shè)置最大并發(fā)呼叫設(shè)置來對負(fù)載進(jìn)行均衡處理。例如,以下4個對端peers的能力支持可以設(shè)置為:
- 30 通道執(zhí)行編碼轉(zhuǎn)換, 32 for PSTN GW
- 100 語音郵箱通道和 10 for transcoding
- 50 voicemail channels and 300 for conferencing
- 10 voicemail, 10 conference,10 transcoding and 32 PSTN GW
ID | GROUP | SIP URI | RESOURCES |
1 | 1 | sip:10.0.0.11 | tran-30;pstr=32 |
2 | 1 | sip:10.0.0.12 | vm=100;tran=10 |
3 | 1 | sip:10.0.0.13 | vm=50;conf-300 |
4 | 1 | sip:10.0.0.14 | vm= 10;conf=10;tran=10;pstn=32 |
5LB模塊的調(diào)用
如果使用OpenSIPS的LB模塊,用戶首先需要添加LB組,設(shè)置所要求的媒體資源。OpenSIPS可以根據(jù)提供的媒體資源的支持設(shè)置來檢查其負(fù)載狀態(tài)。實(shí)現(xiàn)檢查的腳本也非常簡單,示例如下:
# 1表示group_id
if (!load_balance("1","transc;pstn")) {
sl_send_reply("500","Service full");
exit;
}
load_balance 將會對此組中的媒體服務(wù)器進(jìn)行檢查,如果有錯誤的話(可能編碼能力不足,可能FXO/E1端口被占用,不能落地),返回錯誤消息。
6LB流程選擇邏輯和lb資源處理討論
在OpenSIPS的系統(tǒng)中,和調(diào)度模塊有著非常大的不同,調(diào)度模塊無需關(guān)心對端的處理能力是否可以支持當(dāng)前的呼叫,dispatch模塊直接會發(fā)生到目的地地址。但是,LB需要經(jīng)過資源計(jì)數(shù),最后找到一個平衡的最佳資源。具體來說,OpenSIPS目的地選擇的邏輯需要經(jīng)過以下4個步驟:
通過目的地組ID選擇一個可用的對端peers
此目的地組中選擇一個支持可用資源的peer。例如,如果一個呼叫需要編碼的話,LB模塊必須選擇到可用的編碼服務(wù)器
此目的地組的可用服務(wù)器中,找到當(dāng)前每一個服務(wù)器的的負(fù)載狀態(tài),是否到達(dá)最大負(fù)載
從最小負(fù)載的媒體服務(wù)器選擇一個均衡處理“最佳”媒體服務(wù)器資源
以上介紹相對比較難以理解,讀者最好結(jié)合具體的選擇算法來獲取最佳的資源目的地。

在以上的示例中,通過執(zhí)行以上腳本以后,資源選擇的邏輯處理結(jié)果如下:
1因?yàn)槟_本呼叫選擇的是trans和PSTN,所以只能選擇1和4服務(wù)器進(jìn)行處理。
2重新評價(jià)呼叫以后的資源占用和剩余資源:
- 服務(wù)器1 ,編碼占用10個通道,PSTN占用18個通道
- 服務(wù)器4,編碼占用占用9個通道,PSTN占用16個通道剩余資源:
- 服務(wù)器1,編碼資源剩余20個通道(默認(rèn)30-20),PSTN剩余14通道
- 服務(wù)器4,編碼資源剩余1個通道(默認(rèn)10-9),PSTN剩余16個通道
3針對每個資源服務(wù)器來說,判斷最小可用資源:
4服務(wù)器1最小可用資源是14(比20下),服務(wù)器4最小可用資源是1。注意,這里是針對兩個媒體服務(wù)器所有資源來說的。
從步驟3中選擇最小資源中的最大資源值-因?yàn)榉⻊?wù)器1的14比服務(wù)器4中的1大,因此,服務(wù)器1作為一個最終資源來使用。
以上邏輯示例僅說明正常狀態(tài)下的LB的處理,在實(shí)際腳本處理中,我們?nèi)匀恍枰獙艚惺∵M(jìn)行處理。通過t_on_failure做失效轉(zhuǎn)移和關(guān)閉目的地的流程。具體示例腳本如下:
route[do_lb] {
If(!lb_start(1, "tran")) { # 編碼轉(zhuǎn)換業(yè)務(wù)處理
send_reply(503,"Service Unavailable");
exit;
t_on_failure("lb_failover");
t_relay(0;
}
failure route[lb_failover]{
if (failure condition) {
Ib_disable_dst); #避免再次將來的呼叫使用此peer資源
if (!lb_next(){
t _reply[503,"Service Unavailable");
exit;
t_on_failure("lb_ failover");
t relay();
}
}
雖然我們從腳本示例中看到的邏輯相對比較簡單,但是,在實(shí)際應(yīng)用環(huán)境中,負(fù)載均衡需要完全自動化的處理,并且在OpenSIPS LB模塊啟用以后不能再手動調(diào)整目的地資源。因?yàn),目的地資源的調(diào)用是一個動態(tài)的數(shù)據(jù),大量呼叫狀態(tài)下,我們不能完全模擬出當(dāng)前實(shí)時的狀態(tài)。lb_next 已經(jīng)啟動,當(dāng)前的動態(tài)數(shù)據(jù)(因?yàn)樽罴奄Y源是變化的)不可能再次進(jìn)行處理,所以,LB目的地資源的調(diào)用是非常關(guān)鍵的步驟,它要求的系統(tǒng)資源也非常大。另外,因?yàn)槟康牡刭Y源在呼叫過程中已經(jīng)被locked,我們不能使用其他的外部命令再次對其進(jìn)行干預(yù)管理。所以,其負(fù)載處理能力和lb_start 時的負(fù)載基本上相同,因此,在使用lb_next方面,它增加了系統(tǒng)的維護(hù)復(fù)雜程度,如果處理不好的話,可能導(dǎo)致系統(tǒng)性問題,和呼叫失敗。
7LB模塊在運(yùn)行狀態(tài)時的命令執(zhí)行
比較幸運(yùn)的是,OpenSIPS通過CLI命令可以提供一定的對LB模塊的管理能力,包括reload LB模塊刷新DB數(shù)據(jù)庫,重增系統(tǒng)資源對媒體服務(wù)器的支持lb_resize。在某些應(yīng)用場景中(電話會議服務(wù)),系統(tǒng)管理員可能不完全了解最終的會議人數(shù),如果最終會議人數(shù)超過了系統(tǒng)資源的支持,或者CPU負(fù)載很高的話,系統(tǒng)需要針對后續(xù)的呼叫進(jìn)行選擇,讓其路由到其他的相對空閑的會議服務(wù)器。如果會議服務(wù)器CPU資源不能支持更多呼叫的話,對會議服務(wù)器的呼叫并發(fā)進(jìn)行限制。
8負(fù)載均衡在電話會議場景中的挑戰(zhàn)和解決思路
電話會議對用戶來說是非常熟悉的一個應(yīng)用場景,用戶端操作看起來也非常簡單。如果單使用一臺媒體服務(wù)器實(shí)現(xiàn)其應(yīng)用場景的話,實(shí)際部署也不復(fù)雜。但是,如果前端使用了OpenSIPS的負(fù)載均衡模塊以后,系統(tǒng)部署就會面對很多的問題。幾個比較有挑戰(zhàn)性的問題是:
一個會議室由幾個不同的呼叫構(gòu)成。每個會議人員加入會議有自己的SIP呼叫流程。
為了確保所有會議成員能夠進(jìn)入同一會議室,他們/她們的呼叫必須在同一會議服務(wù)器。
一般情況下,因?yàn)槭褂昧薒B的邏輯,LB需要對資源進(jìn)行重新路由,他們的呼叫可能進(jìn)入到了不同會議服務(wù)器的會議室。
在OpenSIPS針對會議服務(wù)的解決方式可以通過對URL進(jìn)行檢查,然后進(jìn)行路由。通常的針對會議服務(wù)器來說,會議人員需要撥打一個指定的會議室號碼才能進(jìn)入到特定會議室。在LB模塊中,會議呼叫首先需要檢查Request URL確保進(jìn)入到同一會議室。如果第一個請求的URL進(jìn)入到了會議室,會議室啟動以后,后續(xù)的對此URL的呼叫不再做資源檢查,直接通過LB模塊路由到此會議室。具體實(shí)現(xiàn)方式是通過dialog模塊的變量對會議呼叫進(jìn)行路由,路由到會議室服務(wù)器地址。
# 添加一個以撥號碼變量"conf_ bridge"
$dlg_ val(conf_ bridge) =$rU ;
# 添加一個目的地會議服務(wù)器地址變量
"server'$dlg_ val(server) = $du;
另外,在失敗呼叫的路由中也要對以上兩個變量進(jìn)行處理,保證失敗的會議呼叫那個正常進(jìn)入到會議室中。
9負(fù)載均衡模塊的配置示例演示
在本示例中,我們將通過一個簡單示例對兩臺媒體服務(wù)器支持LB負(fù)載的處理演示。在此示例的設(shè)置過程中,用戶需要根據(jù)要求完成以下的配置和界面添加工作。
首先,我們需要修改cfg 配置文件,添加對LB模塊的支持加載。
loadmodule "load_balancer.so"
modparam("load_balancer", "db_url",
"mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
modparam("load_balancer", "probing_interval", 30)
modparam("load_balancer", "probing_from", "sip:lb@sip.domain.com")
然后對to_media 路由腳本增加支持:
route[to_media] {
xlog("routing to media servers via load balancer\n");
if (!lb_start(1, "channel")) {
send_reply(500,"No route to Media");
exit;
}
xlog("Using media server $du (RURI=$ru) \n");
t_on_failure("media_failover");
t_relay();
exit;
}
修改失效路由中的路由,支持to_media 路由規(guī)則:
failure_route[media_failover] {
if (t_was_cancelled())
exit;
if ( t_check_status( "[56][0-9][0-9]" ) ||
。╰_local_replied("all") && t_check_status("408"))) {
# media server failover -> mark it as disabled
xlog("Media server routing failed with reply $T_reply_code\n");
lb_disable_dst();
# try another media server, if available
if (!lb_next()) {
xlog("no more media servers available\n");
t_reply(503,"Service Unavailable");
exit;
}
# send the call to the new media server
xlog("Trying the new $du media server\n");
t_on_failure("media_failover");
t_relay();
}
}
保存cfg文件,重新啟動OpenSIPS。
接下來,用戶需要訪問OpenSIPS控制界面,然后通過界面添加LB模塊的配置路由,添加路由以后需要點(diǎn)擊reload 按鈕重新加載數(shù)據(jù)庫數(shù)據(jù)。

如果需要重新編輯數(shù)據(jù)時,用戶也可以編輯LB模塊資源路由:

添加LB模塊以后,注意目的地的狀態(tài),確保DB加載和目的地地址可用。
最后對LB模塊配置示例進(jìn)行測試。使用兩個UAC終端對不同媒體服務(wù)器進(jìn)行呼叫,查看LB狀態(tài)和資源占用情況。通過UAC測試呼叫對媒體服務(wù)器進(jìn)行呼叫,sngrep抓包截圖:

通過LB模塊的負(fù)載均衡管理以后,用戶可以通過CLI命令或者界面狀態(tài)查看具體資源的使用情況。對媒體服務(wù)器的呼叫需要配置dialplan 的撥號規(guī)則,通過撥號規(guī)則路由到相關(guān)的媒體服務(wù)器端(Asterisk或者FreeSWITCH),在媒體服務(wù)器端也要確保正確的呼入規(guī)則能夠被觸發(fā),然后UAC才能看到最終的成功呼叫。關(guān)于媒體服務(wù)器的呼入配置,用戶可以自己根據(jù)自己的業(yè)務(wù)場景進(jìn)行配置,例如進(jìn)入會議室,呼出到PSTN或者如果有編碼轉(zhuǎn)換功能的話,可以測試媒體服務(wù)器的編碼轉(zhuǎn)換功能。
10總結(jié)
OpenSIPS的負(fù)載均衡是SIP軟交換中核心的功能,但是其使用部署也比較復(fù)雜,特別是在實(shí)際應(yīng)用場景中,例如電話會議的處理方面。本文檔重點(diǎn)介紹了如何實(shí)現(xiàn)負(fù)載均衡的資源選擇和其4個邏輯步驟,并且介紹了如何處理lb_next問題,還有電話會議中如何確保會議室的進(jìn)入。最后,筆者給出了一個負(fù)載均衡的配置示例和兩臺媒體服務(wù)器的對接呼叫測試,通過界面添加DB,媒體服務(wù)器資源進(jìn)行呼叫測試。
在比較大型的呼叫應(yīng)用場景中,媒體服務(wù)器資源具有不同的支持能力,負(fù)載均衡也需要靈活地處理。這是一個非常大的挑戰(zhàn),用戶需要在部署負(fù)載均衡之前首先考慮到其業(yè)務(wù)的擴(kuò)展如何能夠保證負(fù)載均衡的穩(wěn)定性。筆者還是建議讀者通過多種場景進(jìn)行不同的測試,預(yù)估出其部署風(fēng)險(xiǎn),保證其平臺的正常工作。平衡是為了更好地發(fā)展,發(fā)展是為了更好地平衡。
參考資料:
https://opensips.org/Documentation/Tutorials-LoadBalancing-1-9
https://www.vmware.com/content/dam/digitalmarketing/vmware/en/pdf/techpaper/voip-performance-vsphere5-white-paper.pdf
Varun C,https://pdfs.semanticscholar.org/c3c4/f143ae0243345276bdd618c9f47a26fbec45.pdf
www.freesbc.cn
www.freepbx.org.cn
www.asterisk.org.cn
- 關(guān)于Asterisk文檔,參考:www.asterisk.org.cn
- 融合通信/IPPBX/FreePBX商業(yè)解決方案:www.hiastar.com
- 最新Asterisk完整中文用戶手冊詳解:www.asterisk.org.cn
- Freepbx/FreeSBC技術(shù)文檔: www.freepbx.org.cn
- 如何使用免費(fèi)會話邊界控制器-FreeSBC,qq技術(shù)分享群:334023047
- 關(guān)注微信公眾號:asterisk-cn,獲得有價(jià)值的通信行業(yè)技術(shù)分享