標籤:.com port ber tco parent pop hid image 相同
本文來自EasyDarwin團隊Fantasy(fantasy(at)easydarwin.org)
一. EasyDarwin網路模型介紹
EventContext負責監聽全部網路讀寫事件。EventContext::RequestEvent每次插入一個監聽事件到
監聽列表(select 檔案描寫敘述符集合),EventThread::Entry()死迴圈監聽加入到該FD_SET的全部檔案描寫敘述符的
事件。Entry()->select_waitevent()每次返回下一個要處理的事件節點,包含事件處理對象的雜湊key,以及事件類型。
然後投遞到線程池中的某一個線程的任務隊列。注意這裡是每個線程維護自己的任務隊列。
相關代碼,ProcessEvent->Signal()。當中實現了一個簡單的均衡演算法,決定投遞到哪一個線程的任務隊列。EventContext每處理完一個事件,會刪掉監聽的檔案描寫敘述符。然後執行完後會再次調用RequestEvent()插入到監聽列表。並且啟用監聽(往管道寫資料)。TaskThread::Entry()負責處理上面投遞過來的任務,執行虛方法Run()。相關代碼。theTimeout = theTask->Run()。全部網路模組均會繼承並實現Task類的Run()方法。
二. select和epoll的區別
select核心實現,
sys_select()->do_select(){ for(;;) { 迴圈遍曆FD_SET看是否有事件發生, }}
select最大僅僅支援1024個檔案描寫敘述符。原因#define __FD_SETSIZE 1024,定義超過1024會造成處理效能上的下降;
epoll核心實現,
網路事件中斷中調用ep_poll_callback(),將網路事件加入到epoll隊列。這樣,epoll_wait()等待的時候,就不會像select迴圈,由於隊列中的每個事件都是有效。
由此看來epoll比select效率高,並且隊列不受限制。可以隨意大小。
可是假設select命中到有效時間的機率也很高的時候,它倆效率是幾乎相同的。
三. 把EasyDarwin的網路模型換成epoll
實現過程比較簡單。依照前面select提供的介面,挨個實現一遍。然後把調用的地方加以作業系統類型的宏開關,相容windows的編譯。
實現之後,調試卻花了很長時間,剛開始發現線程池在插入監聽事件的時候會出現資源競爭,程式執行了一段時間後就出現異常了,不讀取推送的資料了。經過review代碼發現應該是沒有加鎖導致插入的時候資源競爭,有的沒有成功插入,所以監聽不到事件。後面加鎖後經過調試,避免了一些死結問題後,穩定執行了幾天沒有出現故障。
經過年前後將近2個月的開發和穩定調試、測試。EasyDarwin開源流媒體server最終成功將底層select網路模型改動最佳化成epoll網路模型。將EasyDarwin流媒體server在網路處理的效率上提升到了還有一個檔次(這裡得感謝EasyDarwin開源團隊成員Fantasy的無私貢獻,是他犧牲寶貴的業餘歇息時間,連夜奮戰開發和調試。才幹取得EasyDarwin底層改造的成果)。
眾所周知,select模型在處理大並發量的網路請求上具有一些瓶頸。預設在Linux上同一時候可以處理的網路連接數FD_SETSIZE為1024,儘管可以通過改動FD_SETSIZE的定義大小,但在FD_SETSIZE大於1024時。由於select模型先天的原因。對網路事件無法做到及時準確定位。其處理效能上並沒有得到同步的提升,所以,帶來的就是整個流媒體server在並發量上的瓶頸;而改動成epoll網路模型之後,其網路事件的處理效能得到提升,再加上EasyDarwin架構上的優勢,採用線程池。任務隊列及Reactor技術,使得網路事件可以很高效地被感知、處理(這裡的任務隊列還涉及到一個無鎖隊列的最佳化,這個在興許的部落格中會詳細分析),這樣,使得整個EasyDarwin流媒體server具有很高效的事件處理能力。並且經過長時間的測試。穩定性很好!
須要說明的是,EasyDarwin在Windows端還是沿用的select網路模型。從眼下的情況上來看。大並發量需求的項目多數部署在Linux系統上,Windows上EasyDarwin作為小規模或者研究型項目,全然可以滿足需求。所以,將EasyDarwin+IOCP列入以後的開發計劃中;
Epoll模型基本的代碼在EasyDarwin Github上,檔案夾位置在:https://github.com/EasyDarwin/EasyDarwin/tree/master/CommonUtilitiesLib。主要檔案是:epollEvent.h和epollEvent.cpp
EasyDarwin開源流媒體server項目還在一直進行更加高效能的最佳化,項目地址:https://github.com/EasyDarwin
擷取很多其它資訊
郵件:[email protected]
WEB:www.EasyDarwin.org
Copyright ? EasyDarwin.org 2013-2016
EasyDarwin開源流媒體server將select改為epoll的方法