1、筆者在前面的講座中也提到過(guò),兩個(gè)開(kāi)源平臺的技術(shù)架構基本上是完全一致的,但是可能在解釋上可能有所不同。今天,我們分別對各自的架構做一個(gè)說(shuō)明。這里,我們首先介紹Kamailio 技術(shù)架構。根據以下圖例我們可以看到,Kamailio的核心的架構包括九大部分。它們分別是:

- SIP Parser 負責解析SIP消息內容。
- SIP Transport Layer 負責收發(fā)UDP,SCTP,TUP和TLS加密。
- Configuration file Interpreter負責處理各種配置文件,并且在runtime執行。
- Variabels Framework是一個(gè)API接口負責處理系統偽變量,選擇和轉譯功能。
- Locking Manager負責對內部資源的同步管理。
- DNS Resolver負責執行DNS查詢(xún)和對結果進(jìn)行緩存處理。
- Control Interface API是一個(gè)API接口負責處理系統的控制命令。
- Memory Manager負責對private和shared 內存進(jìn)行管理。
- Modules Interface 是一個(gè)API接口,負責加載模塊和導入已導出參數和函數。

2、OpenSIPS 核心模塊介紹和kamailio模塊基本上是一樣架構。只是模塊的命名稍微有差異。
筆者會(huì )根據Kamailio的命名來(lái)進(jìn)一步介紹各個(gè)模塊的具體功能。
3、因為兩個(gè)軟交換的架構基本一致,所以我們這里我們重點(diǎn)介紹一下Kamailio的九大模塊的基本功能:
- SIP Parser解析器。Kamailio有自己的解析器,其主要作用是支持SIP proxy的解析需要。和一些SIP終端的解析器相比,它可以同時(shí)處理上千個(gè)transactions和dialogcs,而一般終端只能同時(shí)處理幾個(gè)dialogcs。另外,解析器可以?xún)H處理它本身需要的消息內容,無(wú)需全部解析,同時(shí)對解析的消息進(jìn)行緩存處理。解析器可以對SIP消息體中的消息頭和body解析解析并且根據需要對部分信息進(jìn)行刪除添加等功能。
- Memory Manager內存管理器。Kamailio有自己的內存管理工具對其進(jìn)程進(jìn)行管理。因為Kamailio是基于多進(jìn)程設計的平臺,它本身的同步管理管理比較簡(jiǎn)單。有時(shí),為了配合第三方的軟件平臺,系統又需要共享內存的支持。Kamailio的內存管理器可以按照不同的內存需求來(lái)靈活調整內存大小。啟動(dòng)時(shí)附加不同的內存參數設置來(lái)實(shí)現共享內存和私有內存的配置。啟動(dòng)命令設置時(shí)用戶(hù)需要根據內存命令來(lái)設置。例如,kamailio -m 521 -M 8 表示 使用的是512M的共享內存,使用 8M的私有內存。這里,讀者一定要注意大小寫(xiě)的區別。M表示設置的是私有內存,m表示設置的是共享內存。另外,配置的變量存儲在共享內存還是私有內存完全取于變量類(lèi)型。大部分情況下,一般的SIP屬性參數保存在私有內存($ru,$fu,$dbr等),一些avp變量/shv變量則保存在共享內存。但是明確一點(diǎn),如果當正在處理一個(gè)SIP請求時(shí),想保存此變量值用于處理相應的響應時(shí),則必須使用共享內存變量。

Locking manager 制鎖管理。通過(guò)API支持互斥管理和內存范圍管理。因為有時(shí)系統同時(shí)使用一個(gè)變量時(shí),我們需要更新一個(gè)變量時(shí),如果不先鎖定此變量,就不可能對其進(jìn)行同步更新,因為可能同時(shí)有其他進(jìn)程正在使用此變量。此管理器的目的就是通過(guò)先鎖定變量,更新此變量后,然后再其變量進(jìn)行解鎖操作。例如:
- lock(“x”);// 鎖定變量x
- $shv()=$shv(x)+5 // 使用共享內存保存更新后的變量
- unlock(); // 解鎖操作
Transport layer 傳輸層管理。此模塊支持IPv4和IPv6,支持的傳輸方式包括UDP,TCP,TLS和SCTP。傳輸方式完全取決于用戶(hù)的配置文件設置,軟交換本身可以同時(shí)支持UDP和TCP傳輸。SCTP協(xié)議設計目的是專(zhuān)門(mén)針對SIP技術(shù)架構的,但是目前使用的場(chǎng)景比較少,所以也沒(méi)有大規模商用。
Configuration File Interpreter 配置文件解析器。從字面意思我們就可以知道,此接口負責處理對軟交換配置文件的解析。軟交換配置文件是一個(gè)文本配置文件,它主要包括三個(gè)部分的配置:全局變量設置自定義變量和預處理的文件,模塊名稱(chēng)和參數設置和路由管理設置負責SIP路由管理。在軟交換啟動(dòng)時(shí),系統會(huì )加載經(jīng)過(guò)優(yōu)化的配置文件存儲在內存中,以便在runtime時(shí)使用。解析器會(huì )編譯正則表達式,檢測靜態(tài)變量,檢測條件語(yǔ)句判斷,重構路由和子路由路徑結構,在runtime環(huán)境中添加各種函數的變量值。
Variabels Framework 接口對變量進(jìn)行處理。軟交換本身支持了很多種變量,而且因為以前項目的繼承和兼容性的問(wèn)題,導致現在的支持兩種變量:pseudo-variables(來(lái)自于OpenSER/Kamailio,使用$開(kāi)始變量標注) 和selects(來(lái)自于SER,使用@開(kāi)始變量標注)。關(guān)于具體每個(gè)變量的學(xué)習,大家可以查閱兩個(gè)軟交換的官方文檔。
DNS Reslover 負責軟交換的DNS查詢(xún)處理。目前軟交換支持的DNS類(lèi)型包括:A(IPv4),AAAA(IPv6),CNAME別名查詢(xún),SRV查詢(xún)(服務(wù)器主機和端口),NAPTR(傳輸方式,服務(wù)地址和端口),TXT(服務(wù)器獲取的任意數據內容)。軟交換的DNS模塊可以支持基于DNS SRV結果的均衡負載處理和基于DNS記錄的黑名單管理。
Control Interface 接口負責提供兩種對軟交換進(jìn)行控制的接口命令,這兩個(gè)接口包括RPC接口(SER開(kāi)發(fā)),MI管理接口(Openser/Kamailio開(kāi)發(fā)而來(lái))。兩種接口都提供同樣的功能-對軟交換通過(guò)人工命令進(jìn)行互動(dòng)管理,例如獲取內存內容,后臺加載數據,在運行時(shí)修改一些這些命令,發(fā)送SIP消息等功能。
Modules Interface 此核心模塊負責加載系統執行時(shí)需要的相關(guān)模塊和其模塊的傳遞參數,并且導入負責導入以導出的函數參數等數值。此模塊是軟交換非常重要的核心模塊,所有的軟交換認證模塊,數據庫對接模塊,其他定位服務(wù),路由等都需要相應的模塊提前加載才能執行。這個(gè)模塊接口對于一個(gè)非常龐大的模塊數量,用戶(hù)可以到官方網(wǎng)站查閱對應的模塊使用說(shuō)明。
4、前面我們提到過(guò),Kamailio是一個(gè)多進(jìn)程的軟交換平臺,進(jìn)程數量是一個(gè)變量,數量的多少取決于配置文件的設置。對于每個(gè)Kamailio的實(shí)例來(lái)說(shuō),每個(gè)進(jìn)程都有其特別的功能角色。它們包括以下多種進(jìn)程維護功能:
主進(jìn)程維護功能:進(jìn)程啟動(dòng),監控解析文件配置,設置創(chuàng )建環(huán)境變量,創(chuàng )建SIP worker 進(jìn)程和定時(shí)器。
TCP 維護進(jìn)程:管理TCP worker 和連接的過(guò)程。
SIP TCP 接收方:處理通過(guò)TCP收到的數據過(guò)程。
SIP UDP 接收方:處理通過(guò)UDP端口的數據。
SIP SCTP 接收方:處理通過(guò)SCTP傳輸的數據。
Control Interface Receiver:負責處理MI/RPC 命令的數據交互,它們可能是FIFO,TCP/UDP/UNIXSOCK或者XML,RPC 接收方數據。
定時(shí)器進(jìn)程:此進(jìn)程處理正在運行的周期性的任務(wù),可能是core 模塊或其他模塊調用的。定時(shí)器進(jìn)程可能是Core 定時(shí)器(main timers和slow times)和自定義的定時(shí)器包括NAT ping 定時(shí)器(發(fā)送保持NAT 存活數據包)和rtimer定時(shí)器,在定時(shí)器內執行執行一個(gè)配置文件的路由設置。
Modue specific wokers:此進(jìn)程是通過(guò)啟動(dòng)各種模塊執行具體的任務(wù),例如異步處理等。
5、這里我們特別討論一下關(guān)于子進(jìn)程對系統性能的影響(children和tcp_children)。通過(guò)以上的介紹,我們知道軟交換配置中的參數配置可以影響到子進(jìn)程(默認設置會(huì )產(chǎn)生8個(gè)進(jìn)程-默認children=4,兩個(gè)UDP socket)數量的實(shí)現,這些進(jìn)程數量的多少會(huì )直接影響系統的執行性能。這些參數決定著(zhù)SIP worker的進(jìn)程數量。因此我們必須注意,所有進(jìn)程都是在啟動(dòng)時(shí)創(chuàng )建,啟動(dòng)以后,在運行環(huán)境中,不能再次創(chuàng )建進(jìn)程或者結束結束進(jìn)程。
可能有讀者問(wèn),進(jìn)程數量到底多少是合適的?不幸的是,沒(méi)有一個(gè)完整的公式可以計算出一個(gè)運行環(huán)境中究竟需要多少進(jìn)程,這都完全取決于配置文件的復雜程度和腳本邏輯的復雜程度。當然,創(chuàng )建的進(jìn)程越多,則需要更多的并行處理機制來(lái)處理數據流量。但是,如果創(chuàng )建了太多的進(jìn)程則會(huì )導致系統性能下降。很多的進(jìn)程處理的切換需要系統時(shí)間,內部同步和制鎖都需要時(shí)間處理。因此,讀者需要在系統進(jìn)程數量和系統穩定性上做一個(gè)平衡。
在配置文件的路由邏輯腳本中,很多的邏輯運算是依賴(lài)于CPU IO操作和計算能力。例如,基本上無(wú)IO操作的DNS,數據庫簡(jiǎn)單操作和HTTP等。相對比較消耗IO操作的大量頻繁的數據庫查詢(xún)命令,DNS 查詢(xún)等。如果沒(méi)有涉及太多的IO操作的進(jìn)程,系統的默認進(jìn)程設置基本上可以滿(mǎn)足這些要求;如果是大量的IO操作的進(jìn)程,需要用戶(hù)創(chuàng )建更多的進(jìn)程來(lái)保證運行的穩定性。如果涉及到太多的寫(xiě)入操作或者數據庫連接等邏輯,用戶(hù)也要考慮數據庫的連接問(wèn)題。
用戶(hù)可以通過(guò)每個(gè)SIP消息對IO操作的平均數和IO操作的平均時(shí)間來(lái)大致估算所需進(jìn)程數量。大部分的軟交換用戶(hù)可能沒(méi)有注意到children參數具體的細節,其實(shí),這些參數的設置一開(kāi)始就已經(jīng)限定了系統的性能,有一些開(kāi)發(fā)人員僅是一味地強調CPU性能和內存大小。讀者可以查看cfg中的全局變量參數fork,children和tcp_children來(lái)進(jìn)行配置。另外,如果系統確實(shí)確認不需要某些傳輸協(xié)議的話(huà),可以通過(guò)配置文件來(lái)關(guān)閉這些傳輸協(xié)議。但是,一定要注意,UDP是不能關(guān)閉的,它總是處于開(kāi)啟狀態(tài)。
硬件服務(wù)器的CPU,網(wǎng)卡都是直接影響CPU性能的重要指標,另外硬件中斷(CPU,網(wǎng)卡,硬盤(pán),語(yǔ)音卡)的優(yōu)先級同樣影響服務(wù)器的性能。優(yōu)先級高的中斷可以?xún)?yōu)先運行執行某些進(jìn)程,優(yōu)先級低的中斷則可能稍后執行。如果把網(wǎng)卡的優(yōu)先級設置的比較低,則可能直接影響軟交換對SIP數據的處理和鎖切換時(shí)間。用戶(hù)可能需要一些系統工具來(lái)嘗試調整所需要的優(yōu)先級(irqblance)。
Italo Dacosta和他的團隊的軟交換(OpenSER)性能研究中也明確了關(guān)于數據庫和進(jìn)程數量影響軟交換性能的測試數據。讀者可以根據參考鏈接做進(jìn)一步的研究。

6、在本章節的討論中,筆者和大家分享了Kamailio九大核心接口的主要功能和各自負責的任務(wù)處理,另外,也介紹了系統創(chuàng )建的主要進(jìn)程和各個(gè)進(jìn)程對特定任務(wù)的處理。為了幫助讀者能夠掌握軟交換穩定性的配置問(wèn)題,筆者也重點(diǎn)介紹了進(jìn)程數量的設置,CPU(核數量)或IO操作的影響和硬件服務(wù)器的CPU,網(wǎng)卡以及相應中斷的優(yōu)先級問(wèn)題。最后,筆者和大家分享了國外一位研究人員對OpenSER的性能測試數據,讀者可以根據這些測試環(huán)境來(lái)進(jìn)一步掌握本章節的重點(diǎn)內容。
參考資料:
http://blog.csrpswitch.com/tuning-kamailio-for-high-throughput-and-performance/
Italo Dacosta, Improving Authentication Performance of Distributed SIP Proxies

關(guān)注微信公眾號:asterisk-cn,獲得有價(jià)值的行業(yè)分享。訪(fǎng)問(wèn)5060社區-開(kāi)源IPPBX論壇獲得技術(shù)幫助:www.ippbx.org.cn/www.hiastar.com