epool 與websocket

epool

最近看高并發(fā)websocket服務(wù)器的代碼,其中設(shè)計(jì)到epool的使用,參考了這篇文章:
https://segmentfault.com/a/1190000003063859

有一些心得:

  1. IO 為什么是阻塞的? 首先,當(dāng)用戶程序讀寫IO設(shè)備時(shí),一定會進(jìn)行系統(tǒng)調(diào)用,從而發(fā)生內(nèi)核切換,內(nèi)核調(diào)用硬件讀寫數(shù)據(jù),并將數(shù)據(jù)通過
    內(nèi)核的緩存空間拷貝到用戶的緩存空間,再切換回用戶的內(nèi)核進(jìn)程。這中間過程,用戶進(jìn)程是不會進(jìn)行讀寫的,因此IO是阻塞的。
  2. 非阻塞IO呢? 所謂的異步IO是指,用戶態(tài)程序讀取IO時(shí),如果讀寫不到數(shù)據(jù),則立刻返回。過一會,用戶進(jìn)程再次去讀取IO,以此來輪詢。
  3. IO 多路復(fù)用。select/pool/epool 屬于單個(gè)process就可以處理多個(gè)IO,他們會輪詢所負(fù)責(zé)的所有socket,當(dāng)有數(shù)據(jù)到達(dá)的時(shí)候,就通知用戶進(jìn)程。
    就是通過一個(gè)機(jī)制同時(shí)等待多個(gè)文件描述符,任何一個(gè)感興趣的時(shí)間就緒的時(shí)候,就能通知用戶進(jìn)程。
  4. epool跟前面兩者的好處在于:1, 沒有文件描述符個(gè)數(shù)的限制;2, 即使文件描述符數(shù)目增大,也不會影響效率。

了解下epool就三個(gè)函數(shù) epool_create, epool_ctl, epoll_wait,分別用于創(chuàng)建epool,將文件描述符-事件放入epool,等到事件就緒。epool的wait能返回
就緒的所有文件描述符,而select必須用戶去輪詢所有的文件描述符。

兩種工作模式:

  1. 水平觸發(fā)(默認(rèn))
    告訴你某個(gè)文件描述符就緒了,如果不做任何處理,下次還會觸發(fā)。
  2. 邊緣觸發(fā)
    內(nèi)核第一次通知你,認(rèn)為你會去對文件做相應(yīng)的處理,之后狀態(tài)再次變化的時(shí)候才會通知你,效率更高。

我們怎么使用epool實(shí)現(xiàn)高并發(fā)的:

首先服務(wù)器listen在tcp端口上,把這個(gè)文件描述符放入pool,事件是 read|oneshot。(就是只觸發(fā)一次)
掛載的回調(diào)函數(shù):
對listener accept,得到的connection的,首先進(jìn)行websocket upgrade。之后文件描述符號,放入pool,事件是 read| EdgeTriger.
掛載的回調(diào)函數(shù)是: 判斷event如果是Hup,則close連接,文件描述符移除出pool。否則讀取完整message列表,并處理。
最后resume重新把listen的文件描述符繼續(xù)(不然oneshot只觸發(fā)一次)。

一些有趣的bug:

  1. 測試高并發(fā)大量連接之后,一段時(shí)間后,新進(jìn)來的連接無法建立。原因是這些大量測試連接不會去讀取數(shù)據(jù),協(xié)程池被耗盡,導(dǎo)致write阻塞,但是connection write之前
    是有設(shè)置deadline,但是deadline不生效,是由于netpool將偷偷將連接設(shè)置成block ip。
  2. 某一些websocket連接會斷掉,客戶端是發(fā)送了pong響應(yīng)的,但是服務(wù)端認(rèn)為沒有讀到,認(rèn)為客戶端超時(shí)。原因是每次觸發(fā)讀時(shí)間的時(shí)候,發(fā)現(xiàn)有時(shí)一個(gè)tcp package會有多個(gè)message,
    但是原先的reader只讀取一個(gè)message就去做處理,而netpool是edgeTriger的形式,沒有新的數(shù)據(jù)進(jìn)來的時(shí)候,不會再次觸發(fā)讀取,導(dǎo)致漏了pong數(shù)據(jù),修改成讀盡多個(gè)message再返回處理。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 必備的理論基礎(chǔ) 1.操作系統(tǒng)作用: 隱藏丑陋復(fù)雜的硬件接口,提供良好的抽象接口。 管理調(diào)度進(jìn)程,并將多個(gè)進(jìn)程對硬件...
    drfung閱讀 3,763評論 0 5
  • IO概念 Linux的內(nèi)核將所有外部設(shè)備都可以看做一個(gè)文件來操作。那么我們對與外部設(shè)備的操作都可以看做對文件進(jìn)行操...
    消失er閱讀 2,056評論 0 5
  • title: 論事件驅(qū)動與異步IOtag: 事件驅(qū)動 異步IOcategories: notes 轉(zhuǎn)載自人云思云 ...
    cmustard閱讀 1,028評論 0 0
  • 在看kafka的生產(chǎn)者基于NIO構(gòu)建網(wǎng)絡(luò)通信層NetworkClient的時(shí)候,發(fā)覺自己對網(wǎng)絡(luò)通信的相關(guān)知識(同步...
    紹圣閱讀 1,101評論 0 1
  • 1. 硬鏈接和軟連接區(qū)別 硬連接-------指通過索引節(jié)點(diǎn)來進(jìn)行連接。在Linux的文件系統(tǒng)中,保存在磁盤分區(qū)...
    杰倫哎呦哎呦閱讀 2,534評論 0 2

友情鏈接更多精彩內(nèi)容