背景說(shuō)明
I/O多路復(fù)用就通過(guò)一種機(jī)制,可以監(jiān)視多個(gè)描述符澎办,一旦某個(gè)描述符就緒(一般是讀就緒或者寫(xiě)就緒)嘲碱,能夠通知程序進(jìn)行相應(yīng)的讀寫(xiě)操作金砍。但select,poll麦锯,epoll本質(zhì)上都是同步I/O恕稠,因?yàn)樗麄兌夹枰谧x寫(xiě)事件就緒后自己負(fù)責(zé)進(jìn)行讀寫(xiě),也就是說(shuō)這個(gè)讀寫(xiě)過(guò)程是阻塞的离咐,而異步I/O則無(wú)需自己負(fù)責(zé)進(jìn)行讀寫(xiě)谱俭,異步I/O的實(shí)現(xiàn)會(huì)負(fù)責(zé)把數(shù)據(jù)從內(nèi)核拷貝到用戶(hù)空間。
epoll跟select都能提供多路I/O復(fù)用的解決方案宵蛀。在現(xiàn)在的Linux內(nèi)核里有都能夠支持昆著,其中epoll是Linux所特有,而select則應(yīng)該是POSIX所規(guī)定术陶,一般操作系統(tǒng)均有實(shí)現(xiàn)
Select
Select模型使用單個(gè)線(xiàn)程監(jiān)聽(tīng)客戶(hù)端連接請(qǐng)求凑懂,連接建立成功后注冊(cè)讀寫(xiě)事件到Selector中,Selector調(diào)用操作系統(tǒng)內(nèi)核的方法注冊(cè)讀寫(xiě)事件梧宫,然后Selector阻塞等待讀寫(xiě)事件接谨。
客戶(hù)端發(fā)送數(shù)據(jù)到服務(wù)端,操作系統(tǒng)內(nèi)核輪訓(xùn)socket連接的讀寫(xiě)事件塘匣,當(dāng)存在讀寫(xiě)事件時(shí)脓豪,生成對(duì)應(yīng)的可讀列表readList和可寫(xiě)列表writeList,應(yīng)用層遍歷讀寫(xiě)事件列表readList和writeList忌卤,做相應(yīng)的讀寫(xiě)操作扫夜,進(jìn)行后續(xù)的業(yè)務(wù)處理。
從上面的流程可以看出驰徊,主要存在兩個(gè)問(wèn)題:
(1) 輪訓(xùn)笤闯,每次調(diào)用時(shí)都會(huì)對(duì)連接進(jìn)行線(xiàn)性遍歷,所以隨著連接數(shù)的增加會(huì)造成遍歷速度慢的“線(xiàn)性下降性能問(wèn)題”棍厂,性能瓶頸可能會(huì)出現(xiàn)颗味。
(2) 連接數(shù)量。連接數(shù)量首先影響輪訓(xùn)效率牺弹,其次浦马,如果連接數(shù)很多,連接在應(yīng)用層和內(nèi)核層的相互copy例驹,也會(huì)有一定的性能影響捐韩。
epoll
epoll模型主要解決了select模型的兩個(gè)問(wèn)題:
- 輪訓(xùn)問(wèn)題, epoll模型是在創(chuàng)建一個(gè)socket連接時(shí)鹃锈,會(huì)在操作系統(tǒng)內(nèi)核層的epoll模型中 注冊(cè)此socket連接的callback函數(shù)荤胁,當(dāng)后續(xù)檢測(cè)到存在讀寫(xiě)事件時(shí),通過(guò)此回調(diào)函數(shù)屎债,將事件記錄到epoll模型中仅政。
- 連接句柄符復(fù)制問(wèn)題垢油。 epoll模型在創(chuàng)建socket連接時(shí),就會(huì)把連接建立的句柄符保存到操作系統(tǒng)內(nèi)核層的epoll模型中圆丹,這樣就避免后續(xù)在應(yīng)用層和內(nèi)核層來(lái)回復(fù)制從而產(chǎn)生的性能問(wèn)題滩愁。
epoll模型在操作系統(tǒng)內(nèi)核層的實(shí)現(xiàn)可以參考這篇文章(深入理解select、poll和epoll及區(qū)別)(https://blog.csdn.net/wteruiycbqqvwt/article/details/90299610)
總結(jié)思考
- epoll 的事件通知機(jī)制辫封,內(nèi)核和應(yīng)用層的mmp機(jī)制還需要具體看下硝枉。
- 通過(guò)epoll 和 select的對(duì)比,可以發(fā)現(xiàn)方案是逐步演化的倦微,聯(lián)系到目前的業(yè)務(wù)架構(gòu)中也是類(lèi)似的妻味,架構(gòu)不是一步到位的,避免過(guò)度設(shè)計(jì)欣福,針對(duì)痛點(diǎn)問(wèn)題及時(shí)調(diào)整即可责球。
- epoll的事件通知機(jī)制類(lèi)似于設(shè)計(jì)模式的觀察者模式,spring的事件通知機(jī)制拓劝,可以極大的解耦和提高性能雏逾,后面的業(yè)務(wù)中也要著重學(xué)習(xí)這種設(shè)計(jì)思路。