最近在參與乙個海量級(20000以上)遠端連線的伺服器設計,由於使用者要求的硬體平台僅限於linux,因此選擇了epoll模型來實現對海量客戶端連線的處理。
先聊一下epoll模型的基本情況。(一般來說,非海量級客戶端連線的伺服器,可能用不到epoll模型。一方面是由於epoll模型不能跨平台,另一方面初學者面露難色)。使用到epoll_create,epoll_ctl,epoll_wait,close 4個函式。
epoll較之select優越的點,有兩個方面:
1)select操作的socket物件的集合,要受到fd_setsize的限制,各平台的預設值也不一樣(windows上是64,aix、linux、hp、solaris上為1024或2048不等);而epoll操作的socket物件集合僅受系統的控制代碼限制,一般來說,可以達到65535
2) select和epoll的核心實現機制不同。select實現中,kernel每次都要遍歷fd_set中的socket,檢測是否可讀,花費的時間和fd_set中的socket個數成正比;epoll實現中,當有socket可讀時,由核心啟用epoll訂閱的乙個事件,因此節省了sys cpu從而節約了資源,自然就提高了效率
epoll模型提供了二種工作模式:
1) edge triggered (et)
et是高速工作方式,只支援no-block socket。當io事件發生時核心通知事件後不再傳送更多的通知,直到使用者執行的操作導致那個socket(或檔案描述符)事件的改變,也就是說如果使用者不對socket(或檔案描述符)進行io操作,那麼核心也不會再通知事件。
2) level triggered (lt)
lt是預設的工作方式,同時支援block和no-block socket。核心通知事件乙個檔案描述符是否就緒了,然後可以對這個就緒的fd進行io操作。如果使用者不作任何讀、寫操作,核心還是會繼續通知事件的。
更詳細的epoll定義或資訊,參照相關網路資訊或書籍即可。下面,我來描述一下,這個需求中的epoll模型的設計。
一、業務需求如下圖,要求滿足高併發、高效能、高可靠等屬性。
二、流程設計:
1) 主程序
1) net_recv_thfunc工作執行緒
handle_netrecv函式流程
2) net_send_thfunc工作執行緒
epoll模型使用中,注意以下幾個點:
1)避免多個執行緒操作同乙個epoll物件,否則會出現驚群現象,即當乙個可讀epollin或epollout事件到達時,所有執行緒都返回這個事件,但只有乙個線**正能拿到這個事件,其他的執行緒將返回ewouldblock
2)操作epoll物件的執行緒和操作socket的執行緒是否分開,應視後續的處理效率而定。如果接受到socket資料的後續處理效能高,則可以在同一執行緒裡來搞定;否則,需要建立另一類執行緒池,來參與socket資料的後續處理。
3)畢竟,乙個程序內的控制代碼數也有限。如果要適應更加海量的客戶端連線,可採取在同一臺裝置(硬體資源足夠的情況下)或多台裝置上,部署多套「接入管理server」。
採用epoll模型伺服器連線管理器實現
應用場景 在網路伺服器中,需要維護所有連線資訊,通常是以fd做為key,連線資訊結構體做為value。每次有新連線接入時,需求加入乙個對映關係 每次有新資料到達時,需要根據對應的fd查詢到對應的連線資訊結構。通過上面的場景我們可以抽象出來一類資料,資料的特點如下 解決方案 一種解決方案是,把資訊儲存...
18 11 27 高階的伺服器連線 epoll
恢復內容開始 之前的 http 伺服器 都是採用 輪詢的方式 就像 廚師挨個問誰餓了好做飯 一樣 而 epoll 用著高階的 方式 事件通知 直接問誰餓了 同時還和 計算機共享內純 預設閘道器 好像是接到路由器 上面的 mac位址 類似於網絡卡的預設 數值 在路由器上面 有兩個 mac 網絡卡 乙個...
03 02 資料庫連線 會員模型設計
資料庫建立例項 安裝flask sqlalchemy pip3 install i flask sqlalchemy安裝pymysql pip3 install i pymysql定義資料庫連線程式示例 coding utf8 from flask import flask from flask s...