0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

FreeSWITCH高可用部署與云原生集群部署知識分享

LiveVideoStack ? 來源:LiveVideoStack ? 2022-12-29 11:12 ? 次閱讀

大家好,我本次分享的主題是FreeSWITCH高可用部署與云原生集群部署,主要是談一談從高可用到彈性伸縮的一些技術(shù)應(yīng)用。

具體包含以下相關(guān)內(nèi)容:雙機(jī)、三機(jī),到可彈性伸縮的通信集群建設(shè)經(jīng)驗(yàn),包含?對?通話、呼叫中?及?視頻會議、?志監(jiān)控等場景,涉及FreeSWITCH、Kamailio、WebRTC、MCU、SFU、Docker、K8S、ETCD、NATS、Loki等相關(guān)技術(shù)。

主要會介紹我們用到的一些技術(shù),希望能對大家有所幫助。上面提到的一些技術(shù)其實(shí)也不算是新技術(shù),通信技術(shù)已經(jīng)歷幾十年發(fā)展,早在二三十年前大家就已經(jīng)在研究高可用相關(guān)技術(shù)。不過因?yàn)樾聲r(shí)代的發(fā)展,最近大家開始關(guān)注云原生等相關(guān)技術(shù),相應(yīng)基礎(chǔ)設(shè)施產(chǎn)生一些變化,通信與互聯(lián)網(wǎng)的聯(lián)系也越來越緊密,由此產(chǎn)生了更多新的玩法。

01 單點(diǎn)故障

其實(shí),一切的起源都是來自“單點(diǎn)故障”這個(gè)問題,我們就由此展開來進(jìn)行介紹。

f048171c-871d-11ed-bfe3-dac502259ad0.jpg

A和B兩個(gè)通信的實(shí)體,兩個(gè)電話(人)通過一臺服務(wù)器進(jìn)行通信,當(dāng)然這個(gè)服務(wù)器可以是FreeSWITCH,也可以是任何其它服務(wù)器。假設(shè)這臺服務(wù)器由于通信鏈路中斷或者是網(wǎng)絡(luò)連接中斷,A和B則無法完成通信,這就是單點(diǎn)故障的起源。

f05d1464-871d-11ed-bfe3-dac502259ad0.jpg

那要想解決這個(gè)單點(diǎn)故障,就需要另外的服務(wù)器通過迂回路由或是其它辦法來克服單點(diǎn)故障的問題。

02雙機(jī)HA

一般來說,克服這個(gè)單點(diǎn)故障的方法就是雙機(jī)HA(High Availability),即主備高可用。

f0796236-871d-11ed-bfe3-dac502259ad0.jpg

雙機(jī)HA的主要原理是:有一臺主機(jī)和一臺備機(jī),假如主機(jī)出現(xiàn)問題斷連,備機(jī)可以接替成為主機(jī)繼續(xù)進(jìn)行工作,如此不斷進(jìn)行主備交換。主機(jī)與備機(jī)為同一IP地址,對于A和B來說可能感知的到或者根本感知不到主備機(jī)所進(jìn)行的切換,因?yàn)橥ㄓ崟r(shí)A和B看到的僅僅只是IP地址,當(dāng)任何一臺服務(wù)器切換到主機(jī)時(shí),它就占有了對外服務(wù)的IP地址,這個(gè)IP地址我們就叫做虛擬的IP,也叫業(yè)務(wù)IP或浮動IP。本身每臺服務(wù)器底層還有一個(gè)IP,但對外提供服務(wù)的IP(即A和B看到的IP)其實(shí)是虛擬IP。

這樣當(dāng)服務(wù)器發(fā)生切換的時(shí)候,A和B仍然是和原來的IP進(jìn)行通話,他們可能會感覺到網(wǎng)絡(luò)的短暫卡頓,然后恢復(fù)正常,而感知不到服務(wù)器是否有進(jìn)行切換,這就是主備高可用的原理。

f093f308-871d-11ed-bfe3-dac502259ad0.jpg

為了實(shí)現(xiàn)主備高可用,由于主服務(wù)器和備服務(wù)器之間有一些數(shù)據(jù)需要同步,所以就需要一種數(shù)據(jù)同步機(jī)制。

f0a7b596-871d-11ed-bfe3-dac502259ad0.jpg

當(dāng)然這個(gè)數(shù)據(jù)同步的機(jī)制有很多種,例如通過日志、消息隊(duì)列等等,在FreeSWITCH中主要是通過數(shù)據(jù)庫來同步這些數(shù)據(jù)。主服務(wù)器會實(shí)時(shí)將A和B(A和B可能有成千上萬個(gè))通話的數(shù)據(jù)寫入到數(shù)據(jù)庫當(dāng)中,備機(jī)可以在數(shù)據(jù)庫當(dāng)中查詢數(shù)據(jù),一旦發(fā)生主備切換,備機(jī)從數(shù)據(jù)庫當(dāng)中取得數(shù)據(jù),重新建立通話場景,A和B就可以繼續(xù)進(jìn)行通話。

f0c01122-871d-11ed-bfe3-dac502259ad0.jpg

在這種情況下,數(shù)據(jù)庫也就成為了一個(gè)單點(diǎn),為了解決這個(gè)問題,數(shù)據(jù)庫同樣需要主備高可用。

f0dfdaca-871d-11ed-bfe3-dac502259ad0.jpg

FreeSWITCH的主備切換原理:首先主機(jī)包含一個(gè)Param,參數(shù)為:,如果我們開啟此參數(shù),它就會實(shí)時(shí)的將通話數(shù)據(jù)寫入數(shù)據(jù)庫當(dāng)中。當(dāng)然這個(gè)會有一定的開銷,因?yàn)樾枰獙?shí)時(shí)的寫入數(shù)據(jù)庫,比如每秒有一千路通話、一萬路通話,它的開銷就會很大,所以這種雙機(jī)切換會對系統(tǒng)的吞吐量有一定影響。但在一些必要的場景下,我們往往是需要犧牲一些性能來更好的實(shí)現(xiàn)高可用的。

當(dāng)備機(jī)發(fā)生切換的時(shí)候,備機(jī)會執(zhí)行一個(gè) sofia recover 命令,從數(shù)據(jù)庫中取得數(shù)據(jù)重建通話的場景,向A和B發(fā)送 reINVITE。前面我們說A和B感知不到,其實(shí)也能感知到,因?yàn)锳和B收到了重新建連的邀請,繼續(xù)進(jìn)行通話。一般這個(gè)通話過程大概在1-3秒內(nèi)解決,A和B只是覺得會短暫的卡頓,不用掛斷重新呼叫。

f1037b7e-871d-11ed-bfe3-dac502259ad0.jpg

我們先排除數(shù)據(jù)庫的影響(默認(rèn)數(shù)據(jù)庫是主備高可用的),來看FreeSWITCH的主備高可用。

為了能準(zhǔn)確感知進(jìn)行主服務(wù)器和備服務(wù)器之間的切換,需要有一個(gè)東西叫心跳(心跳線),一般心跳線在之前都是用串口線,因?yàn)樾奶皇呛唵蔚膫鲙讉€(gè)字節(jié)的信息,對帶寬的要求不大。但現(xiàn)在在一些虛擬機(jī)中,不包含物理的串口,就只能用網(wǎng)線來實(shí)現(xiàn)。通過一個(gè)網(wǎng)線,不停的有心跳,備機(jī)可以借此感知主機(jī)的狀態(tài),一旦產(chǎn)生主機(jī)崩潰、斷連,備機(jī)會接管IP。

當(dāng)然這個(gè)情況下也可能會產(chǎn)生誤判,考慮到心跳線本身的斷開影響,我們可以通過兩根心跳線或雙網(wǎng)卡的方法避免出現(xiàn)這種誤判的情況??傊?,我們需要更多的機(jī)制來保護(hù)系統(tǒng),避免出現(xiàn)兩個(gè)服務(wù)器同時(shí)綁定同一個(gè)IP,同時(shí)寫入服務(wù)器導(dǎo)致服務(wù)器錯(cuò)亂的情況產(chǎn)生。

f1269ac8-871d-11ed-bfe3-dac502259ad0.jpg

當(dāng)然,這種情況下會有一些問題,兩臺機(jī)器作為一臺機(jī)器使用,可能會造成資源的浪費(fèi)。還有一套方式是負(fù)載分擔(dān)(Load Balance),A和B之間有50%的話務(wù)分別放置于兩臺主機(jī),兩臺主機(jī)可以同時(shí)達(dá)到滿負(fù)荷承載。但這種情況同樣存在一定問題,假設(shè)原本每臺可以承受一千路通話,兩臺配合總共可以承受兩千路通話,當(dāng)其中一臺主機(jī)出現(xiàn)問題,另一臺在滿負(fù)載的情況下,實(shí)際上系統(tǒng)的吞吐量只能達(dá)到一千,就會發(fā)生擁塞發(fā)生問題。

所以說一般主備負(fù)載分擔(dān)的情況下,我們會保證兩臺FreeSWITCH主機(jī)每臺的話務(wù)量不要超過其設(shè)計(jì)容量的50%,這樣是比較安全的。當(dāng)然,這樣算起來我們實(shí)際上還是有50%的浪費(fèi),我們也可以采取通信降級的策略,當(dāng)一臺主機(jī)出現(xiàn)故障時(shí),僅使用另外一臺主機(jī),根據(jù)實(shí)際業(yè)務(wù)需求,保證部分通話連接的正常使用。

f148c878-871d-11ed-bfe3-dac502259ad0.jpg

不過負(fù)載分擔(dān)對于A和B會有一定的要求,前面我們說到主備的方式,A和B都只能看到一臺服務(wù)器(實(shí)際上是兩臺服務(wù)器),是一個(gè)IP地址。但是在負(fù)載分擔(dān)的情況下,A和B都能看到兩臺機(jī)器,這就需要一定的邏輯(在A和B上做),需要能夠分發(fā)比如將50%的話務(wù)量分到一臺主機(jī),剩余50%分到另外一臺主機(jī)。而且有時(shí)候兩臺主機(jī)的性能不一樣,可能一個(gè)是64核,另一個(gè)是32核,需要根據(jù)主機(jī)性能對話務(wù)量進(jìn)行分配,比如一個(gè)60%,一個(gè)40%。這樣就會對A的要求比較高,需要能夠感知主機(jī)來進(jìn)行負(fù)載的分發(fā)。

f15e06de-871d-11ed-bfe3-dac502259ad0.jpg

在實(shí)際的部署當(dāng)中,我們一般都是采用這樣的結(jié)構(gòu)(如圖所示)。FreeSWITCH作為媒體服務(wù)器,前面再放上代理服務(wù)器,一般是用Kamailio或者openSIPS做代理。Kamailio只代理SIP就是指處理通信的建立和分發(fā),一臺Kamailio后端可以放很多的FreeSWITCH。因?yàn)镕reeSWITCH要過媒體,要進(jìn)行錄音、質(zhì)檢、分析等等媒體的處理,所以FreeSWITCH的處理能力就不如Kamailio強(qiáng)。這樣前面放一個(gè)Kamailio,后端可以放很多FreeSWITCH進(jìn)行通信。

當(dāng)然Kamailio需要主備高可用,而Kamailio和FreeSWITCH之間是用Load Balance,這樣用HA+負(fù)載分擔(dān)的方式就完成了一種比較大的通信集群。而且由于A和B兩側(cè)的業(yè)務(wù)邏輯有可能會不一樣,比如說一側(cè)是中繼,一側(cè)是話務(wù)員是本次的系統(tǒng)電話,這時(shí)我們可以放兩個(gè)不同的Kamailio,管理起來會更方便一些。

當(dāng)然我們也可以使用一個(gè)Kamailio,將A和B放在一側(cè),但這樣的話腳本和邏輯的判斷上就會比較復(fù)雜。因?yàn)楸仨氁袛嗤ㄔ捠怯葾還是B過來的,還是從FreeSWITCH過來的,需要判斷呼叫的方向,邏輯會相對比較復(fù)雜。

f16fe868-871d-11ed-bfe3-dac502259ad0.jpg

還有一種情況就是異地災(zāi)備,什么是異地災(zāi)備?舉個(gè)例子,我們可能有兩個(gè)機(jī)房分別在北京和上海,都用FreeSWITCH和主備高可用,這樣平常主要通過北京的機(jī)房,一旦出現(xiàn)問題可以通過迂回路由經(jīng)由上海的機(jī)房進(jìn)行通信。

但是異地災(zāi)備同樣需要一些數(shù)據(jù)的同步,這就又對A提出了一定要求,因?yàn)锳面對的是北京和上海兩個(gè)機(jī)房。所以說高可用是無窮無盡的,只要有需求只要改架構(gòu)就需要相應(yīng)的考慮,但萬變不離其宗,其實(shí)就是HA和負(fù)載均衡這兩種邏輯。當(dāng)然具體地來說,A上可能靠DNS輪詢,也可以將北京或上海的地址直接寫進(jìn)設(shè)備當(dāng)中,自己執(zhí)行策略根據(jù)情況來進(jìn)行切換等等。

f1872a96-871d-11ed-bfe3-dac502259ad0.jpg

那么,我們來看B這一側(cè)。A和B進(jìn)行通話,有可能會呼叫進(jìn)來之后執(zhí)行IVR有些應(yīng)用,這些應(yīng)用同樣需要主備高可用。比如有人打電話進(jìn)來,Kamailio是負(fù)責(zé)信令的,F(xiàn)reeSWITCH負(fù)責(zé)媒體,但是具體的邏輯是由應(yīng)用來負(fù)責(zé)的,需要由它來告訴FreeSWITCH應(yīng)該什么時(shí)候處理媒體、什么時(shí)候錄音、放音等等,所以應(yīng)用側(cè)同樣需要主備高可用。

f19a242a-871d-11ed-bfe3-dac502259ad0.jpg

當(dāng)然,一般的這種IVR我們認(rèn)為它大體都是無狀態(tài)的,接入通話掛斷之后再接入一個(gè)新的通話同樣還是這個(gè)IVR,所以一般都會用負(fù)載分擔(dān)的方式,可以承擔(dān)多個(gè)IVR的業(yè)務(wù)。

f1b4886a-871d-11ed-bfe3-dac502259ad0.jpg

但是有一些服務(wù)它是有狀態(tài)的,比如說呼叫中心當(dāng)中常用的ACD。ACD需要check坐席的狀態(tài),以及隊(duì)列的狀態(tài),有多少客戶在等待、有多少坐席在服務(wù)、哪個(gè)坐席正在跟客戶溝通、哪個(gè)坐席正處于空閑,它需要跟蹤這些狀態(tài)。一般來說對于這種有狀態(tài)的服務(wù),還是要采用主備高可用的方式。當(dāng)然,雙機(jī)HA同樣可能會出現(xiàn)兩臺機(jī)器同時(shí)發(fā)生問題的情況,這時(shí)候我們就擴(kuò)展到 —— 三機(jī)。

03Raft

三臺機(jī)器的場景更為麻煩,由此我們引入了一個(gè)協(xié)議叫做Raft,還有一個(gè)叫做PaxOS,不過現(xiàn)在比較常用的還是Raft協(xié)議。

f1e07862-871d-11ed-bfe3-dac502259ad0.jpg

Raft其實(shí)是一個(gè)共識協(xié)議,它的主要作用是做Log。首先它是用一個(gè)分布式的系統(tǒng),分布式系統(tǒng)主要是解決容錯(cuò)的問題。那么怎么解決呢?就是同步日志。比如一臺機(jī)器上的日志,我要將這些日志副本同步到其它的服務(wù)器上去,當(dāng)然我們說到的日志可能也是數(shù)據(jù),數(shù)據(jù)庫數(shù)據(jù)或者通話的數(shù)據(jù)或者是狀態(tài)的數(shù)據(jù)等等。一般來說Raft都是奇數(shù)的,因?yàn)槠渥裱贁?shù)服從多數(shù)的原則,通過投票來進(jìn)行選舉。

f1f98e1a-871d-11ed-bfe3-dac502259ad0.jpg

Raft中包含三個(gè)節(jié)點(diǎn),Leader(領(lǐng)導(dǎo))是一個(gè)主服務(wù)器,所有人會選舉選出一個(gè)Leader來,由Leader來決定什么時(shí)候修改數(shù)據(jù)。然后它會把這些數(shù)據(jù)同步給Follower(追隨者),所有的數(shù)據(jù)會從Leader上進(jìn)行修改,之后會同步到Follower上。正常的情況下,集群內(nèi)有Leader和Follower,數(shù)據(jù)就可以在服務(wù)器間進(jìn)行同步。但又一種情況是作為Leader的主服務(wù)器掛掉了,其它所有的服務(wù)器就會變?yōu)?a target="_blank">Candidate(候選者),有機(jī)會被選舉成為新的Leader,通過這個(gè)機(jī)制可以保證有一臺服務(wù)器是可以保存這些數(shù)據(jù)的。

f2080b0c-871d-11ed-bfe3-dac502259ad0.jpg

但是它雖然能保存數(shù)據(jù)卻不能對外提供服務(wù),Raft集群規(guī)定其中有一臺主機(jī)負(fù)責(zé)寫數(shù)據(jù),另外兩臺負(fù)責(zé)備份,只有集群當(dāng)中有多數(shù)的主節(jié)點(diǎn)和備節(jié)點(diǎn)活著的時(shí)候,比如說3個(gè)死了1個(gè),則還可以繼續(xù)對外提供服務(wù)。但是如果是死了兩個(gè),就不能繼續(xù)對外提供服務(wù)了。

那么,這是為什么?如圖最右側(cè)我們來看,假設(shè)原來的主服務(wù)器與其它服務(wù)器斷開鏈接,此時(shí)它還是能正常進(jìn)行服務(wù)。而另外的兩臺服務(wù)器會根據(jù)當(dāng)前情況判斷,重新選舉出一臺作為主服務(wù)器。此時(shí),整個(gè)集群當(dāng)中就會同時(shí)出現(xiàn)兩臺主服務(wù)器產(chǎn)生沖突。所以一定要遵循少數(shù)服從多數(shù)的原則,只有當(dāng)整個(gè)集群中有多數(shù)的節(jié)點(diǎn)活著的時(shí)候才能對外提供服務(wù)。

f22508e2-871d-11ed-bfe3-dac502259ad0.jpg

f23c5010-871d-11ed-bfe3-dac502259ad0.jpg

當(dāng)然,如果我們說要把所有的ACD里面都要實(shí)現(xiàn)一個(gè)Raft是很難的。目前有一個(gè)應(yīng)用叫做ETCD,我們可以直接將服務(wù)連接到ETCD上,它會告訴我們誰是主誰是備。但是這樣又帶來了一個(gè)問題,本來三臺機(jī)器就可以,我們還需要另外再裝三臺ETCD,這樣會帶來更大的開銷和浪費(fèi),多用了一倍的資源。

f24ad55e-871d-11ed-bfe3-dac502259ad0.jpg

但是當(dāng)我們的集群比較大的時(shí)候,比如除了ACD外我們還有其它服務(wù)如BCD、CDE等等。如果各種微服務(wù)的數(shù)量比較多,可以公用一個(gè)ETCD的話,相比較而言開銷也就沒那么大了。

f2717876-871d-11ed-bfe3-dac502259ad0.jpg

簡單的總結(jié)一下:

雙機(jī)可以提?可靠性,但投?資源和獲得回報(bào)不成正?;

為了節(jié)省服務(wù)器,把不同的服務(wù)放到相同的物理服務(wù)器或虛擬機(jī)上,可能適得其反;

集群可以提?可靠性,但只有集群?夠?,資源才能有效利?;

雙機(jī)需要的服務(wù)器數(shù)量是偶數(shù)的,?少2臺;

分布式系統(tǒng)(集群)需要的服務(wù)器數(shù)量是奇數(shù)的,?少3臺。

f28ccf0e-871d-11ed-bfe3-dac502259ad0.jpg

一般的來說,有一臺FreeSWITCH服務(wù)器就夠了,如果想雙機(jī)設(shè)備的話就需要兩臺服務(wù)器,如果需要數(shù)據(jù)庫的話就是四臺。有可能還會放Nginx代理HTTP,還有可能會放Kamailio來代理SIP。當(dāng)然我們主要使用NATS,這是一個(gè)消息隊(duì)列。然后使用Etcd來做選主,有可能使用Redis來做緩存,還有可能做日志、監(jiān)控等各種服務(wù)器。還有可能rtpengine、存儲、業(yè)務(wù)系統(tǒng)......

總之,要是想建立一個(gè)可靠的系統(tǒng)至少需要十幾臺服務(wù)器,它對外所能提供的服務(wù)能力也超不過一臺服務(wù)器的服務(wù)。所以如果集群規(guī)模比較小,那就沒有什么意義,投入天文數(shù)字但實(shí)際上整體的收益很小。如果想要集群規(guī)模做的足夠大,類似云服務(wù),那么投入多少臺服務(wù)器其實(shí)都無所謂了,因?yàn)殚_銷是相對比較小了。當(dāng)然,這些最終還是需要根據(jù)業(yè)務(wù)本身來做權(quán)衡。

04XSwitch實(shí)踐

接下來介紹一些XSwitch的具體實(shí)踐。

f2c78c52-871d-11ed-bfe3-dac502259ad0.jpg

XSwitch即XSwitch集群,一般來說最小的配置就是雙機(jī),主備高可用,F(xiàn)reeSWITCH和PostgreSQL放在一塊。

f2e6dada-871d-11ed-bfe3-dac502259ad0.jpg

對于有一定預(yù)算的客戶,我們就建議他們將數(shù)據(jù)庫獨(dú)立出來,放在獨(dú)立的服務(wù)器上,總共4臺服務(wù)器。Nginx一般我們可以跟FreeSWITCH放在一起,然后有可能我們會放Kamailio。

f300942a-871d-11ed-bfe3-dac502259ad0.jpg

如果預(yù)算充足也可以將它們都獨(dú)立出來,這樣后面就可以放更多的FreeSWITCH。

f31f1cec-871d-11ed-bfe3-dac502259ad0.jpg

再就是異地的,負(fù)載分擔(dān)。

f370367c-871d-11ed-bfe3-dac502259ad0.jpg

因?yàn)閃ebRTC只有媒體, 所以就是直接到FreeSWITCH,信令可以通過Nginx或者Kamailio實(shí)現(xiàn),因?yàn)樾帕疃际腔赪ebSocket來做的,這是WebRTC的高可用。當(dāng)然,媒體前面我們提到有個(gè)rtpengine也可以做代理,可以把后臺的FreeSWITCH隱藏起來,這就是更復(fù)雜的一些應(yīng)用了。

f37f35dc-871d-11ed-bfe3-dac502259ad0.jpg

XSwitch如何實(shí)現(xiàn)多租戶呢?其實(shí)我們有好多種方式,一種就是Per tenant per FreeSWITCH,每個(gè)租戶給它一臺FreeSWITCH,每個(gè)FreeSWITCH一個(gè)Docker,使用同一個(gè)數(shù)據(jù)庫,我們用的是PostgreSQL,里面可以天然的分Schema,每個(gè)Schema都是彼此隔離的,這樣的話可以給每個(gè)租戶分一個(gè)Schema。

f38fe012-871d-11ed-bfe3-dac502259ad0.jpg

也就是每個(gè)租戶一個(gè)域名,每個(gè)租戶一個(gè)Docker,每個(gè)租戶一個(gè)Schema,數(shù)據(jù)庫是同一個(gè)。前面放一個(gè)sbc,用Kamailio來做信令的代理,當(dāng)然sbc現(xiàn)在我們是單機(jī)部署的,以后也可以做HA。

f3aa5bea-871d-11ed-bfe3-dac502259ad0.jpg

具體的代碼其實(shí)我們就寫了一個(gè)映射表,因?yàn)槲覀儸F(xiàn)在集群規(guī)模比較小,還沒有放數(shù)據(jù)庫,通過域名就可以直接查到對應(yīng)的IP地址,來進(jìn)行分發(fā)。我們使用的是Kamailio+Lua。

f3c80bfe-871d-11ed-bfe3-dac502259ad0.jpg

在應(yīng)用側(cè)我們就使用了NATS。NATS是一個(gè)消息隊(duì)列,所以它具有消息隊(duì)列的一些基本特性,比如說Pub/Sub來進(jìn)行推送,還有一個(gè)就是Queue Groups,可以通過一個(gè)隊(duì)列進(jìn)行訂閱,這種情況下就可以做負(fù)載分擔(dān)。生產(chǎn)者生成了一條消息,消費(fèi)者可以負(fù)載分擔(dān)的消費(fèi)這些消息。

f3d45698-871d-11ed-bfe3-dac502259ad0.jpg


那么我們就用它來做集群的應(yīng)用:來了一個(gè)電話到Kamailio進(jìn)行分發(fā),分發(fā)到不同的FreeSWITCH,通過NATS分配給不同的Controller,這個(gè)Controller就是應(yīng)用側(cè),應(yīng)用側(cè)會控制通話的邏輯。

當(dāng)來了一個(gè)電話到了FreeSWITCH以后,NATS會分給某一個(gè)Controller,這個(gè)時(shí)候Controller就跟某一臺FreeSWITCH建立了一個(gè)虛擬的對應(yīng)關(guān)系,在這個(gè)電話的生存期間它就可以控制這路電話的通話行為和呼叫流程。

當(dāng)然,這個(gè)Controller也可以額外增加,F(xiàn)reeSWITCH也可以。NATS也連接到了Kamailio,Kamailio也可以感知到NATS,這時(shí)候如果我們擴(kuò)展、彈性伸縮,F(xiàn)reeSWITCH不夠用我們又加了幾臺,這個(gè)時(shí)候FreeSWITCH就會給NATS發(fā)一個(gè)消息,NATS會把這個(gè)消息發(fā)給Kamailio,Kamailio就感知到我現(xiàn)在有了6臺FreeSWITCH,它就會重新計(jì)算它的路由表,我們用的是dispatcher模塊,重載dispatcher模塊的數(shù)據(jù),然后它就會把新的通話分發(fā)給新的FreeSWITCH,這樣就完成了一個(gè)擴(kuò)容,這也就是彈性伸縮。

彈性伸縮的“伸”還是比較容易的,只需要往上加機(jī)器就行?!翱s”才是比較困難的,有時(shí)候需要等所有的話務(wù)量都去掉之后才能進(jìn)行。

當(dāng)然,“縮”還有一個(gè)就是可能大家都認(rèn)為的,比如其中一臺機(jī)器掛掉了,我重啟一下。其實(shí)重啟之后它就不是原來那臺機(jī)器了,我們這邊用的都是FreeSWITCH的UUID,重啟之后UUID會發(fā)生改變。雖然IP地址有可能變有可能不變,但我們認(rèn)為它是變了,因?yàn)槭且慌_新的機(jī)器了。

所以說在這個(gè)集群里面,即使是重啟了以后,它也不是原來那臺機(jī)器了。我們在哲學(xué)里曾學(xué)過:“?不能兩次踏?同?條河流”就是這個(gè)意思。如果想要做集群,那就要把它做成是無狀態(tài)的最好,這樣才能大規(guī)模的分發(fā)和復(fù)用。

所以說使用的機(jī)制主要是Docker和K8S。當(dāng)然,將FreeSWITCH放在K8S里面并不容易,首先我們先放到Docker里面,先完成容器化,然后再放到K8S里面。因?yàn)镵8S它是一個(gè)網(wǎng)絡(luò),優(yōu)點(diǎn)就是不知道它在哪臺物理機(jī)上運(yùn)行,想啟動就啟動,想關(guān)閉就關(guān)閉。但是FreeSWITCH、SIP,尤其是RTP,它們有一大堆的端口,就會比較麻煩。

f41999e2-871d-11ed-bfe3-dac502259ad0.jpg

那么,我們是怎么做的呢?我們使?Kamailio做Ingress,負(fù)責(zé)信令進(jìn)來。Kamailio還是雙機(jī),然后它分發(fā)給后端的FreeSWITCH,F(xiàn)reeSWITCH不夠用了就執(zhí)行Scale Up,相反就Scale Down。

f425a2aa-871d-11ed-bfe3-dac502259ad0.jpg

但是具體的我們使用了一個(gè)東西叫做VIP,這個(gè)VIP是我們自己寫的一個(gè)協(xié)議,因?yàn)楝F(xiàn)在的K8S主要是針對HTTP來優(yōu)化的,對SIP類的應(yīng)用就會比較麻煩。所以我們就自己寫了一個(gè)應(yīng)用,在每臺物理機(jī)或者虛擬機(jī)上,都有一個(gè)VIP的服務(wù)。當(dāng)FreeSWITCH啟動的時(shí)候,同樣每臺機(jī)器上也只啟動一個(gè)FreeSWITCH,它告訴VIP打開一對端口,然后VIP就把這些端口通過iptables打開,就可以正常分發(fā)了。萬一這臺機(jī)器死了之后,端口就是空著不用也無所謂,因?yàn)镕reeSWITCH也死了,不會有服務(wù)往這上面發(fā)了。當(dāng)機(jī)器重啟之后,端口仍舊還是使用這幾個(gè)端口段,所以也沒有問題。這種情況下RTP就是直接到FreeSWITCH,前端還是通過Kamailio進(jìn)行分發(fā)SIP。

f44a104a-871d-11ed-bfe3-dac502259ad0.png

這種應(yīng)用就是每個(gè)Node上只運(yùn)??個(gè)FreeSWITCH,每個(gè)Node上運(yùn)??個(gè)vip。當(dāng)然,VIP這個(gè)東西叫做DaemonSet,每臺機(jī)器上只起一個(gè)VIP服務(wù),這個(gè)服務(wù)也在集群當(dāng)中。通過這種方式我們就可以動態(tài)的打開SIP和RTP的端口,這樣可以做彈性的伸縮。這是我們做的一些應(yīng)用。

f465a954-871d-11ed-bfe3-dac502259ad0.jpg

當(dāng)然,如果一個(gè)Node 64核、128核,能不能運(yùn)行多個(gè)FreeSWITCH?可以的,其實(shí)這樣就需要按端口段來分開,可以做成兩個(gè)Pod,一個(gè)占10000-20000,另一個(gè)占30000-50000。這樣的話通過這種方式,保證兩個(gè)FreeSWITCH同時(shí)啟動的時(shí)候互不影響,同樣管理也會更加復(fù)雜。

下面是在Kamailio中使用NATS的一些基本代碼:

f47ce966-871d-11ed-bfe3-dac502259ad0.jpg

f49720c4-871d-11ed-bfe3-dac502259ad0.jpg

05會議

下面還有一種就是會議。

f4c9bf3e-871d-11ed-bfe3-dac502259ad0.jpg

我們平常的負(fù)載分擔(dān)分發(fā)是盡量平均的分發(fā)到不同的FreeSWITCH,這是最好的分發(fā)策略。但是會議不能,會議需要把呼入同一個(gè)會議號的,都分發(fā)到同一臺FreeSWITCH上。這里我們用了Kamailio中一個(gè)“2”的策略,“hash over to URI”。

f4e546fa-871d-11ed-bfe3-dac502259ad0.jpg

當(dāng)然,實(shí)際使用的時(shí)候會議規(guī)模比較大,一臺FreeSWITCH不能滿足,我們需要放到多臺FreeSWITCH上,這個(gè)時(shí)候我們就用了“7”這個(gè)策略,“hash over the content of PVs string”。我們可以自己創(chuàng)建一個(gè)字符串,只要是計(jì)算出來不同的終端,它在一個(gè)組內(nèi),通過分組,只要計(jì)算出來字符串是相同的,就會分配到同一臺FreeSWITCH。

f4f72bae-871d-11ed-bfe3-dac502259ad0.jpg

視頻會議有這么幾種方式:Mesh是無狀態(tài)的,MCU就是所有的東西都通過中間融屏,SFU是通過它進(jìn)行分發(fā),不融屏。

f509a590-871d-11ed-bfe3-dac502259ad0.jpg

f5243d06-871d-11ed-bfe3-dac502259ad0.jpg

f533b06a-871d-11ed-bfe3-dac502259ad0.jpg

我們也會做會議的級聯(lián),通過多個(gè)FreeSWITCH級聯(lián)來實(shí)現(xiàn)較大規(guī)模的會議。

f540cf98-871d-11ed-bfe3-dac502259ad0.jpg

級聯(lián)也會出現(xiàn)一個(gè)問題,叫做“看對眼”,就是出限類似無限循環(huán)的效果,如上圖中的樣子。

f56ab6a0-871d-11ed-bfe3-dac502259ad0.jpg

那么,我們是怎么做的?我們在會議當(dāng)中,首先我們說怎么將兩個(gè)FreeSWITCH的會議串起來。

很簡單,就是在第一臺FreeSWITCH里面 conference 3000(會議號),然后呼叫另外一臺FreeSWITCH也呼3000,另外一臺FreeSWITCH收到呼叫以后,直接conference 3000 加入會議,這個(gè)時(shí)候就是把兩個(gè)會議進(jìn)行串起來。

f57dd2a8-871d-11ed-bfe3-dac502259ad0.png

串起來之后,我們就可以設(shè)置兩個(gè)畫布,第一個(gè)是“video_initial_canvas”,表示我把我的圖像放在哪個(gè)canvas上;第二個(gè)是“video_initial_watching_canvas”,表示我看哪個(gè)canvas。

f5a6387e-871d-11ed-bfe3-dac502259ad0.jpg

通過這種方式,我們也完成了MCU和SFU的互通。我們現(xiàn)在打通了Agora、TRTC以及MediaSoup之類的應(yīng)用。

06日志

最后一個(gè)我想說的就是日志。

f5c7c390-871d-11ed-bfe3-dac502259ad0.jpg

日志很簡單,都有一些現(xiàn)成的服務(wù):

Homer是做SIP的日志的,它的實(shí)現(xiàn)原理就是FreeSWITCH或Kamailio插入一個(gè)Agent,會將收到的消息轉(zhuǎn)發(fā)給它,將SIP的圖畫出來;Loki就是存放日志的,我們會把所有的日志都發(fā)給它;另外還有Zabix、Grafana、Promuthus。

f5e264f2-871d-11ed-bfe3-dac502259ad0.jpg

這里面關(guān)鍵的一點(diǎn)是,每天成千上萬路的通話并發(fā),我們需要知道哪一路通話跟哪一路是相關(guān)的。所以說要有一個(gè)uuid,F(xiàn)reeSWITCH里面每一路通話都有一個(gè)uuid,這個(gè)UUID要跟call-id關(guān)聯(lián)起來。通過call-id就可以找到對應(yīng)的uuid,通過uuid就可以找到另外一條腿的uuid。

f6094e14-871d-11ed-bfe3-dac502259ad0.jpg

上面是呼入,呼出的時(shí)候使用的是這個(gè)參數(shù):outbound-use-uuid-as-callid。

f61cd088-871d-11ed-bfe3-dac502259ad0.jpg

如果FreeSWITCH對外發(fā)出一路呼叫,在SIP當(dāng)中的Call-ID和內(nèi)部的uuid是一致的,這樣就可以找到它們的對應(yīng)關(guān)系,日志和SIP的對應(yīng)關(guān)系。

這樣的話,A進(jìn)來,通過A的Call-ID就可以找到uuid,通過B的uuid就可以找到對應(yīng)的Call-ID。通過Other-Leg-Unique-ID,這個(gè)在事件里面會有,或者Channel-Call-UUID,都能找到到對方,找到A和B。

07總結(jié)

f63c9f76-871d-11ed-bfe3-dac502259ad0.jpg

最后,簡單的總結(jié)一下。通信的集群我們要用到各種各樣的開源軟件,要有雙機(jī)、三機(jī),彈性伸縮,包括?對?通話、呼叫中?及?視頻會議、?志監(jiān)控等場景。最終還是萬變不離其宗,不管使用的是任何軟件,它們的基本原理是不變的。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • RTC
    RTC
    +關(guān)注

    關(guān)注

    2

    文章

    542

    瀏覽量

    66777
  • MCU技術(shù)
    +關(guān)注

    關(guān)注

    0

    文章

    19

    瀏覽量

    5817
  • SFUD
    +關(guān)注

    關(guān)注

    0

    文章

    5

    瀏覽量

    1073

原文標(biāo)題:FreeSWITCH高可用部署與云原生集群部署

文章出處:【微信號:livevideostack,微信公眾號:LiveVideoStack】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    云原生技術(shù)概述 云原生火爆成為升職加薪核心必備

    云原生微服務(wù)可通過分布式部署,大幅提升團(tuán)隊(duì)和日常的工作效率,K8s+Docker+Ceph+Envoy+Istio+Prometheus架構(gòu),目前是各大主流互聯(lián)網(wǎng)首選的技術(shù)方向,掌握云原生微服務(wù)架構(gòu)
    的頭像 發(fā)表于 07-27 10:23 ?1337次閱讀

    Kubernetes Ingress 可靠部署最佳實(shí)踐

    摘要: 在Kubernetes集群中,Ingress作為集群流量接入層,Ingress的高可靠性顯得尤為重要,今天我們主要探討如何部署一套高性能可靠的Ingress接入層。簡介
    發(fā)表于 04-17 14:35

    Hadoop的集群環(huán)境部署說明

    或者是相同,指令多、步驟繁瑣。有的時(shí)候覺得不免覺得很奇怪,這些發(fā)行商為什么不對hadoop的集群環(huán)境部署做一下優(yōu)化呢?幸運(yùn)的是總算是讓我找到了一個(gè)hadoop發(fā)行版集群環(huán)境搭建簡單易用。這里使用的是一款
    發(fā)表于 10-12 15:51

    Flink集群部署方法

    Flink集群部署詳細(xì)步驟
    發(fā)表于 04-23 11:45

    開放應(yīng)用模型(OAM):全球首個(gè)云原生應(yīng)用標(biāo)準(zhǔn)定義與架構(gòu)模型

    Helm charts 這樣的方式來嘗試表達(dá)一個(gè)可部署的應(yīng)用,可一旦部署起來,實(shí)際運(yùn)行的應(yīng)用中卻依舊缺乏以應(yīng)用為中心的約束模型。這些問題都反映出,Kubernetes 以及云原生技術(shù)棧需要一種以應(yīng)用為
    發(fā)表于 10-23 10:06

    redis集群的如何部署

    redis集群部署(偽分布式)
    發(fā)表于 05-29 17:13

    Docker部署Redis服務(wù)器集群的方法

    Docker部署Redis服務(wù)器集群
    發(fā)表于 06-13 09:12

    只需 6 步,你就可以搭建一個(gè)云原生操作系統(tǒng)原型

    優(yōu)化業(yè)務(wù)調(diào)度能力 。最后一步當(dāng)我們擁有了這樣的一套系統(tǒng),我們?nèi)绾尾拍馨阉惭b部署起來?設(shè)想一下,當(dāng)我們面臨一千臺虛擬機(jī)的集群需要部署一個(gè)云原生系統(tǒng)的時(shí)候,我們該怎么做?難道我們需要一臺
    發(fā)表于 09-15 14:01

    華為云中什么是云原生服務(wù)中心

    、統(tǒng)一存儲、全域分發(fā),幫助您簡化云原生服務(wù)的生命周期管理。 UCS深度集成云原生服務(wù)中心的功能,可真正實(shí)現(xiàn)服務(wù)的開箱即用,有效提升云原生服務(wù)能力與質(zhì)量,支持服務(wù)的訂閱、部署、升級、更新
    發(fā)表于 07-27 15:44 ?711次閱讀
    華為云中什么是<b class='flag-5'>云原生</b>服務(wù)中心

    什么是分布式云原生

    什么是分布式云原生 華為云分布式云原生服務(wù)(Ubiquitous Cloud Native Service, UCS)是業(yè)界首個(gè)分布式云原生產(chǎn)品,為企業(yè)提供云原生業(yè)務(wù)部署、管理、應(yīng)用生
    發(fā)表于 07-27 15:52 ?1590次閱讀

    Helm部署MinIO集群

    Helm部署MinIO集群
    的頭像 發(fā)表于 12-03 09:44 ?842次閱讀
    Helm<b class='flag-5'>部署</b>MinIO<b class='flag-5'>集群</b>

    K8S學(xué)習(xí)教程(二):在 PetaExpress KubeSphere容器平臺部署可用 Redis 集群

    前言 Redis 是在開發(fā)過程中經(jīng)常用到的緩存中間件,為了考慮在生產(chǎn)環(huán)境中穩(wěn)定性和可用,Redis通常采用集群模式的部署方式。 在制定Redis
    的頭像 發(fā)表于 07-03 15:30 ?804次閱讀
    K8S學(xué)習(xí)教程(二):在 PetaExpress KubeSphere容器平臺<b class='flag-5'>部署</b><b class='flag-5'>高</b><b class='flag-5'>可用</b> Redis <b class='flag-5'>集群</b>

    什么是云原生MLOps平臺

    云原生MLOps平臺,是指利用云計(jì)算的基礎(chǔ)設(shè)施和開發(fā)工具,來構(gòu)建、部署和管理機(jī)器學(xué)習(xí)模型的全生命周期的平臺。以下,是對云原生MLOps平臺的介紹,由AI部落小編整理。
    的頭像 發(fā)表于 12-12 13:13 ?135次閱讀

    如何選擇云原生機(jī)器學(xué)習(xí)平臺

    當(dāng)今,云原生機(jī)器學(xué)習(xí)平臺因其彈性擴(kuò)展、高效部署、低成本運(yùn)營等優(yōu)勢,逐漸成為企業(yè)構(gòu)建和部署機(jī)器學(xué)習(xí)應(yīng)用的首選。然而,市場上的云原生機(jī)器學(xué)習(xí)平臺種類繁多,功能各異,如何選擇
    的頭像 發(fā)表于 12-25 11:54 ?132次閱讀

    云原生LLMOps平臺作用

    云原生LLMOps平臺是一種基于云計(jì)算基礎(chǔ)設(shè)施和開發(fā)工具,專門用于構(gòu)建、部署和管理大型語言模型(LLM)全生命周期的平臺。以下,是對云原生LLMOps平臺作用的梳理,由AI部落小編整理。
    的頭像 發(fā)表于 01-06 10:21 ?77次閱讀