理解高性能網(wǎng)絡(luò)模型

隨著互聯(lián)網(wǎng)的發(fā)展逻悠,面對(duì)海量用戶高并發(fā)業(yè)務(wù)唉工,傳統(tǒng)的阻塞式的服務(wù)端架構(gòu)模式已經(jīng)無(wú)能為力,由此止吁,本文旨在為大家提供有用的概覽以及網(wǎng)絡(luò)服務(wù)模型的比較,以揭開(kāi)設(shè)計(jì)和實(shí)現(xiàn)高性能網(wǎng)絡(luò)架構(gòu)的神秘面紗

1 服務(wù)端處理網(wǎng)絡(luò)請(qǐng)求

首先看看服務(wù)端處理網(wǎng)絡(luò)請(qǐng)求的典型過(guò)程:

服務(wù)端處理網(wǎng)絡(luò)請(qǐng)求流程圖

可以看到燎悍,主要處理步驟包括:

  • 1敬惦、獲取請(qǐng)求數(shù)據(jù)
    客戶端與服務(wù)器建立連接發(fā)出請(qǐng)求,服務(wù)器接受請(qǐng)求(1-3)
  • 2间涵、構(gòu)建響應(yīng)
    當(dāng)服務(wù)器接收完請(qǐng)求仁热,并在用戶空間處理客戶端的請(qǐng)求,直到構(gòu)建響應(yīng)完成(4)
  • 3勾哩、返回?cái)?shù)據(jù)
    服務(wù)器將已構(gòu)建好的響應(yīng)再通過(guò)內(nèi)核空間的網(wǎng)絡(luò)I/O發(fā)還給客戶端(5-7)

設(shè)計(jì)服務(wù)端并發(fā)模型時(shí)抗蠢,主要有如下兩個(gè)關(guān)鍵點(diǎn):

  • 服務(wù)器如何管理連接,獲取輸入數(shù)據(jù)
  • 服務(wù)器如何處理請(qǐng)求

以上兩個(gè)關(guān)鍵點(diǎn)最終都與操作系統(tǒng)的I/O模型以及線程(進(jìn)程)模型相關(guān)思劳,下面詳細(xì)介紹這兩個(gè)模型

2 I/O模型

2.1 概念理論

介紹操作系統(tǒng)的I/O模型之前迅矛,先了解一下幾個(gè)概念:

  • 阻塞調(diào)用與非阻塞調(diào)用
    • 阻塞調(diào)用是指調(diào)用結(jié)果返回之前,當(dāng)前線程會(huì)被掛起潜叛。調(diào)用線程只有在得到結(jié)果之后才會(huì)返回
    • 非阻塞調(diào)用指在不能立刻得到結(jié)果之前秽褒,該調(diào)用不會(huì)阻塞當(dāng)前線程

兩者的最大區(qū)別在于被調(diào)用方在收到請(qǐng)求到返回結(jié)果之前的這段時(shí)間內(nèi)壶硅,調(diào)用方是否一直在等待。阻塞是指調(diào)用方一直在等待而且別的事情什么都不做销斟。非阻塞是指調(diào)用方先去忙別的事情

  • 同步處理與異步處理

    • 同步處理是指被調(diào)用方得到最終結(jié)果之后才返回給調(diào)用方
    • 異步處理是指被調(diào)用方先返回應(yīng)答庐椒,然后再計(jì)算調(diào)用結(jié)果,計(jì)算完最終結(jié)果后再通知并返回給調(diào)用方
  • 阻塞蚂踊、非阻塞和同步约谈、異步的區(qū)別
    阻塞、非阻塞和同步犁钟、異步其實(shí)針對(duì)的對(duì)象是不一樣的:
    阻塞棱诱、非阻塞的討論對(duì)象是調(diào)用者
    同步、異步的討論對(duì)象是被調(diào)用者

  • recvfrom函數(shù)
    recvfrom函數(shù)(經(jīng)socket接收數(shù)據(jù))涝动,這里把它視為系統(tǒng)調(diào)用

一個(gè)輸入操作通常包括兩個(gè)不同的階段

  • 等待數(shù)據(jù)準(zhǔn)備好
  • 從內(nèi)核向進(jìn)程復(fù)制數(shù)據(jù)

對(duì)于一個(gè)套接字上的輸入操作迈勋,第一步通常涉及等待數(shù)據(jù)從網(wǎng)絡(luò)中到達(dá)。當(dāng)所等待分組到達(dá)時(shí)醋粟,它被復(fù)制到內(nèi)核中的某個(gè)緩沖區(qū)靡菇。第二步就是把數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到應(yīng)用進(jìn)程緩沖區(qū)

實(shí)際應(yīng)用程序在系統(tǒng)調(diào)用完成上面2步操作時(shí),調(diào)用方式的阻塞昔穴、非阻塞镰官,操作系統(tǒng)在處理應(yīng)用程序請(qǐng)求時(shí)處理方式的同步、異步處理的不同吗货,參考《UNIX網(wǎng)絡(luò)編程卷1》,可以分為5種I/O模型

2.2 阻塞式I/O模型(blocking I/O)

阻塞式I/O模型

簡(jiǎn)介
在阻塞式I/O模型中狈网,應(yīng)用程序在從調(diào)用recvfrom開(kāi)始到它返回有數(shù)據(jù)報(bào)準(zhǔn)備好這段時(shí)間是阻塞的宙搬,recvfrom返回成功后,應(yīng)用進(jìn)程開(kāi)始處理數(shù)據(jù)報(bào)

比喻
一個(gè)人在釣魚(yú)拓哺,當(dāng)沒(méi)魚(yú)上鉤時(shí)勇垛,就坐在岸邊一直等

優(yōu)點(diǎn)
程序簡(jiǎn)單,在阻塞等待數(shù)據(jù)期間進(jìn)程/線程掛起士鸥,基本不會(huì)占用CPU資源

缺點(diǎn)
每個(gè)連接需要獨(dú)立的進(jìn)程/線程單獨(dú)處理闲孤,當(dāng)并發(fā)請(qǐng)求量大時(shí)為了維護(hù)程序,內(nèi)存烤礁、線程切換開(kāi)銷較大讼积,這種模型在實(shí)際生產(chǎn)中很少使用

2.3 非阻塞式I/O模型(non-blocking I/O)

非阻塞式I/O模型

簡(jiǎn)介
在非阻塞式I/O模型中,應(yīng)用程序把一個(gè)套接口設(shè)置為非阻塞就是告訴內(nèi)核脚仔,當(dāng)所請(qǐng)求的I/O操作無(wú)法完成時(shí)勤众,不要將進(jìn)程睡眠,而是返回一個(gè)錯(cuò)誤鲤脏,應(yīng)用程序基于I/O操作函數(shù)將不斷的輪詢數(shù)據(jù)是否已經(jīng)準(zhǔn)備好们颜,如果沒(méi)有準(zhǔn)備好吕朵,繼續(xù)輪詢,直到數(shù)據(jù)準(zhǔn)備好為止

比喻
邊釣魚(yú)邊玩手機(jī)窥突,隔會(huì)再看看有沒(méi)有魚(yú)上鉤努溃,有的話就迅速拉桿

優(yōu)點(diǎn)
不會(huì)阻塞在內(nèi)核的等待數(shù)據(jù)過(guò)程,每次發(fā)起的I/O請(qǐng)求可以立即返回阻问,不用阻塞等待茅坛,實(shí)時(shí)性較好

缺點(diǎn)輪詢將會(huì)不斷地詢問(wèn)內(nèi)核,這將占用大量的CPU時(shí)間则拷,系統(tǒng)資源利用率較低贡蓖,所以一般Web服務(wù)器不使用這種I/O模型

2.4 I/O復(fù)用模型(I/O multiplexing)

I/O復(fù)用模型

簡(jiǎn)介
在I/O復(fù)用模型中,會(huì)用到select或poll函數(shù)或epoll函數(shù)(Linux2.6以后的內(nèi)核開(kāi)始支持)煌茬,這兩個(gè)函數(shù)也會(huì)使進(jìn)程阻塞斥铺,但是和阻塞I/O所不同的的,這兩個(gè)函數(shù)可以同時(shí)阻塞多個(gè)I/O操作坛善,而且可以同時(shí)對(duì)多個(gè)讀操作晾蜘,多個(gè)寫(xiě)操作的I/O函數(shù)進(jìn)行檢測(cè),直到有數(shù)據(jù)可讀或可寫(xiě)時(shí)眠屎,才真正調(diào)用I/O操作函數(shù)

比喻
放了一堆魚(yú)竿剔交,在岸邊一直守著這堆魚(yú)竿,直到有魚(yú)上鉤

優(yōu)點(diǎn)
可以基于一個(gè)阻塞對(duì)象改衩,同時(shí)在多個(gè)描述符上等待就緒岖常,而不是使用多個(gè)線程(每個(gè)文件描述符一個(gè)線程),這樣可以大大節(jié)省系統(tǒng)資源

缺點(diǎn)
當(dāng)連接數(shù)較少時(shí)效率相比多線程+阻塞I/O模型效率較低葫督,可能延遲更大竭鞍,因?yàn)閱蝹€(gè)連接處理需要2次系統(tǒng)調(diào)用,占用時(shí)間會(huì)有增加

2.5 信號(hào)驅(qū)動(dòng)式I/O模型(signal-driven I/O)

信號(hào)驅(qū)動(dòng)式I/O模型

簡(jiǎn)介
在信號(hào)驅(qū)動(dòng)式I/O模型中橄镜,應(yīng)用程序使用套接口進(jìn)行信號(hào)驅(qū)動(dòng)I/O偎快,并安裝一個(gè)信號(hào)處理函數(shù),進(jìn)程繼續(xù)運(yùn)行并不阻塞洽胶。當(dāng)數(shù)據(jù)準(zhǔn)備好時(shí)晒夹,進(jìn)程會(huì)收到一個(gè)SIGIO信號(hào),可以在信號(hào)處理函數(shù)中調(diào)用I/O操作函數(shù)處理數(shù)據(jù)

比喻
魚(yú)竿上系了個(gè)鈴鐺姊氓,當(dāng)鈴鐺響丐怯,就知道魚(yú)上鉤,然后可以專心玩手機(jī)

優(yōu)點(diǎn)
線程并沒(méi)有在等待數(shù)據(jù)時(shí)被阻塞他膳,可以提高資源的利用率

缺點(diǎn)

  • 信號(hào)I/O在大量IO操作時(shí)可能會(huì)因?yàn)樾盘?hào)隊(duì)列溢出導(dǎo)致沒(méi)法通知
  • 信號(hào)驅(qū)動(dòng)I/O盡管對(duì)于處理UDP套接字來(lái)說(shuō)有用响逢,即這種信號(hào)通知意味著到達(dá)一個(gè)數(shù)據(jù)報(bào),或者返回一個(gè)異步錯(cuò)誤棕孙。但是舔亭,對(duì)于TCP而言些膨,信號(hào)驅(qū)動(dòng)的I/O方式近乎無(wú)用,因?yàn)閷?dǎo)致這種通知的條件為數(shù)眾多钦铺,每一個(gè)來(lái)進(jìn)行判別會(huì)消耗很大資源订雾,與前幾種方式相比優(yōu)勢(shì)盡失

2.6 異步I/O模型(asynchronous I/O)

異步I/O模型

簡(jiǎn)介
由POSIX規(guī)范定義,應(yīng)用程序告知內(nèi)核啟動(dòng)某個(gè)操作矛洞,并讓內(nèi)核在整個(gè)操作(包括將數(shù)據(jù)從內(nèi)核拷貝到應(yīng)用程序的緩沖區(qū))完成后通知應(yīng)用程序洼哎。這種模型與信號(hào)驅(qū)動(dòng)模型的主要區(qū)別在于:信號(hào)驅(qū)動(dòng)I/O是由內(nèi)核通知應(yīng)用程序何時(shí)啟動(dòng)一個(gè)I/O操作,而異步I/O模型是由內(nèi)核通知應(yīng)用程序I/O操作何時(shí)完成

優(yōu)點(diǎn)
異步 I/O 能夠充分利用 DMA 特性沼本,讓 I/O 操作與計(jì)算重疊

缺點(diǎn)
要實(shí)現(xiàn)真正的異步 I/O噩峦,操作系統(tǒng)需要做大量的工作。目前 Windows 下通過(guò) IOCP 實(shí)現(xiàn)了真正的異步 I/O抽兆,而在 Linux 系統(tǒng)下识补,Linux2.6才引入,目前 AIO 并不完善辫红,因此在 Linux 下實(shí)現(xiàn)高并發(fā)網(wǎng)絡(luò)編程時(shí)都是以 IO復(fù)用模型模式為主

2.5 5種I/O模型總結(jié)

從上圖中我們可以看出凭涂,可以看出,越往后贴妻,阻塞越少切油,理論上效率也是最優(yōu)。其五種I/O模型中名惩,前四種屬于同步I/O澎胡,因?yàn)槠渲姓嬲腎/O操作(recvfrom)將阻塞進(jìn)程/線程,只有異步I/O模型才于POSIX定義的異步I/O相匹配

3 線程模型

介紹完服務(wù)器如何基于I/O模型管理連接绢片,獲取輸入數(shù)據(jù)滤馍,下面介紹基于進(jìn)程/線程模型,服務(wù)器如何處理請(qǐng)求

值得說(shuō)明的是底循,具體選擇線程還是進(jìn)程,更多是與平臺(tái)及編程語(yǔ)言相關(guān)槐瑞,例如C語(yǔ)言使用線程和進(jìn)程都可以(例如Nginx使用進(jìn)程熙涤,Memcached使用線程),Java語(yǔ)言一般使用線程(例如Netty)困檩,為了描述方便祠挫,下面都使用線程來(lái)進(jìn)進(jìn)行描述

3.1 傳統(tǒng)阻塞I/O服務(wù)模型

傳統(tǒng)阻塞I/O服務(wù)模型

特點(diǎn)

  • 采用阻塞式I/O模型獲取輸入數(shù)據(jù)
  • 每個(gè)連接都需要獨(dú)立的線程完成數(shù)據(jù)輸入,業(yè)務(wù)處理悼沿,數(shù)據(jù)返回的完整操作

存在問(wèn)題

  • 當(dāng)并發(fā)數(shù)較大時(shí)等舔,需要?jiǎng)?chuàng)建大量線程來(lái)處理連接,系統(tǒng)資源占用較大
  • 連接建立后糟趾,如果當(dāng)前線程暫時(shí)沒(méi)有數(shù)據(jù)可讀慌植,則線程就阻塞在read操作上甚牲,造成線程資源浪費(fèi)

3.2 Reactor模式

針對(duì)傳統(tǒng)傳統(tǒng)阻塞I/O服務(wù)模型的2個(gè)缺點(diǎn),比較常見(jiàn)的有如下解決方案:

  • 基于I/O復(fù)用模型蝶柿,多個(gè)連接共用一個(gè)阻塞對(duì)象丈钙,應(yīng)用程序只需要在一個(gè)阻塞對(duì)象上等待,無(wú)需阻塞等待所有連接交汤。當(dāng)某條連接有新的數(shù)據(jù)可以處理時(shí)雏赦,操作系統(tǒng)通知應(yīng)用程序,線程從阻塞狀態(tài)返回芙扎,開(kāi)始進(jìn)行業(yè)務(wù)處理
  • 基于線程池復(fù)用線程資源星岗,不必再為每個(gè)連接創(chuàng)建線程,將連接完成后的業(yè)務(wù)處理任務(wù)分配給線程進(jìn)行處理戒洼,一個(gè)線程可以處理多個(gè)連接的業(yè)務(wù)

I/O復(fù)用結(jié)合線程池俏橘,這就是Reactor模式基本設(shè)計(jì)思想

Reactor

Reactor模式,是指通過(guò)一個(gè)或多個(gè)輸入同時(shí)傳遞給服務(wù)處理器的服務(wù)請(qǐng)求的事件驅(qū)動(dòng)處理模式施逾。 服務(wù)端程序處理傳入多路請(qǐng)求敷矫,并將它們同步分派給請(qǐng)求對(duì)應(yīng)的處理線程,Reactor模式也叫Dispatcher模式汉额,即I/O多了復(fù)用統(tǒng)一監(jiān)聽(tīng)事件曹仗,收到事件后分發(fā)(Dispatch給某進(jìn)程),是編寫(xiě)高性能網(wǎng)絡(luò)服務(wù)器的必備技術(shù)之一

Reactor模式中有2個(gè)關(guān)鍵組成:

  • Reactor
    Reactor在一個(gè)單獨(dú)的線程中運(yùn)行蠕搜,負(fù)責(zé)監(jiān)聽(tīng)和分發(fā)事件怎茫,分發(fā)給適當(dāng)?shù)奶幚沓绦騺?lái)對(duì)IO事件做出反應(yīng)。 它就像公司的電話接線員妓灌,它接聽(tīng)來(lái)自客戶的電話并將線路轉(zhuǎn)移到適當(dāng)?shù)穆?lián)系人

  • Handlers
    處理程序執(zhí)行I/O事件要完成的實(shí)際事件轨蛤,類似于客戶想要與之交談的公司中的實(shí)際官員。Reactor通過(guò)調(diào)度適當(dāng)?shù)奶幚沓绦騺?lái)響應(yīng)I/O事件虫埂,處理程序執(zhí)行非阻塞操作

根據(jù)Reactor的數(shù)量和處理資源池線程的數(shù)量不同祥山,有3種典型的實(shí)現(xiàn):

  • 單Reactor單線程
  • 單Reactor多線程
  • 主從Reactor多線程

下面詳細(xì)介紹這3種實(shí)現(xiàn)

3.2.1 單Reactor單線程

單Reactor單線程

其中,select是前面I/O復(fù)用模型介紹的標(biāo)準(zhǔn)網(wǎng)絡(luò)編程API掉伏,可以實(shí)現(xiàn)應(yīng)用程序通過(guò)一個(gè)阻塞對(duì)象監(jiān)聽(tīng)多路連接請(qǐng)求缝呕,其他方案示意圖類似

方案說(shuō)明

  • Reactor對(duì)象通過(guò)select監(jiān)控客戶端請(qǐng)求事件,收到事件后通過(guò)dispatch進(jìn)行分發(fā)
  • 如果是建立連接請(qǐng)求事件斧散,則由Acceptor通過(guò)accept處理連接請(qǐng)求供常,然后創(chuàng)建一個(gè)Handler對(duì)象處理連接完成后的后續(xù)業(yè)務(wù)處理
  • 如果不是建立連接事件,則Reactor會(huì)分發(fā)調(diào)用連接對(duì)應(yīng)的Handler來(lái)響應(yīng)
  • Handler會(huì)完成read->業(yè)務(wù)處理->send的完整業(yè)務(wù)流程

優(yōu)點(diǎn)
模型簡(jiǎn)單鸡捐,沒(méi)有多線程栈暇、進(jìn)程通信、競(jìng)爭(zhēng)的問(wèn)題箍镜,全部都在一個(gè)線程中完成

缺點(diǎn)

  • 性能問(wèn)題:只有一個(gè)線程源祈,無(wú)法完全發(fā)揮多核CPU的性能
    Handler在處理某個(gè)連接上的業(yè)務(wù)時(shí)煎源,整個(gè)進(jìn)程無(wú)法處理其他連接事件,很容易導(dǎo)致性能瓶頸
  • 可靠性問(wèn)題:線程意外跑飛新博,或者進(jìn)入死循環(huán)薪夕,會(huì)導(dǎo)致整個(gè)系統(tǒng)通信模塊不可用,不能接收和處理外部消息赫悄,造成節(jié)點(diǎn)故障

使用場(chǎng)景
客戶端的數(shù)量有限原献,業(yè)務(wù)處理非常快速埂淮,比如Redis姑隅,業(yè)務(wù)處理的時(shí)間復(fù)雜度O(1)

3.2.2 單Reactor多線程

單Reactor多線程

方案說(shuō)明

  • Reactor對(duì)象通過(guò)select監(jiān)控客戶端請(qǐng)求事件,收到事件后通過(guò)dispatch進(jìn)行分發(fā)
  • 如果是建立連接請(qǐng)求事件倔撞,則由Acceptor通過(guò)accept處理連接請(qǐng)求讲仰,然后創(chuàng)建一個(gè)Handler對(duì)象處理連接完成后的續(xù)各種事件
  • 如果不是建立連接事件,則Reactor會(huì)分發(fā)調(diào)用連接對(duì)應(yīng)的Handler來(lái)響應(yīng)
  • Handler只負(fù)責(zé)響應(yīng)事件痪蝇,不做具體業(yè)務(wù)處理鄙陡,通過(guò)read讀取數(shù)據(jù)后,會(huì)分發(fā)給后面的Worker線程池進(jìn)行業(yè)務(wù)處理
  • Worker線程池會(huì)分配獨(dú)立的線程完成真正的業(yè)務(wù)處理躏啰,如何將響應(yīng)結(jié)果發(fā)給Handler進(jìn)行處理
  • Handler收到響應(yīng)結(jié)果后通過(guò)send將響應(yīng)結(jié)果返回給client

優(yōu)點(diǎn)
可以充分利用多核CPU的處理能力

缺點(diǎn)

  • 多線程數(shù)據(jù)共享和訪問(wèn)比較復(fù)雜
  • Reactor承擔(dān)所有事件的監(jiān)聽(tīng)和響應(yīng)趁矾,在單線程中運(yùn)行,高并發(fā)場(chǎng)景下容易成為性能瓶頸

3.2.3 主從Reactor多線程

針對(duì)單Reactor多線程模型中给僵,Reactor在單線程中運(yùn)行毫捣,高并發(fā)場(chǎng)景下容易成為性能瓶頸,可以讓Reactor在多線程中運(yùn)行

主從Reactor多線程

方案說(shuō)明

  • Reactor主線程MainReactor對(duì)象通過(guò)select監(jiān)控建立連接事件帝际,收到事件后通過(guò)Acceptor接收蔓同,處理建立連接事件
  • Accepto處理建立連接事件后,MainReactor將連接分配Reactor子線程給SubReactor進(jìn)行處理
  • SubReactor將連接加入連接隊(duì)列進(jìn)行監(jiān)聽(tīng)蹲诀,并創(chuàng)建一個(gè)Handler用于處理各種連接事件
  • 當(dāng)有新的事件發(fā)生時(shí)斑粱,SubReactor會(huì)調(diào)用連接對(duì)應(yīng)的Handler進(jìn)行響應(yīng)
  • Handler通過(guò)read讀取數(shù)據(jù)后,會(huì)分發(fā)給后面的Worker線程池進(jìn)行業(yè)務(wù)處理
  • Worker線程池會(huì)分配獨(dú)立的線程完成真正的業(yè)務(wù)處理脯爪,如何將響應(yīng)結(jié)果發(fā)給Handler進(jìn)行處理
  • Handler收到響應(yīng)結(jié)果后通過(guò)send將響應(yīng)結(jié)果返回給client

優(yōu)點(diǎn)

  • 父線程與子線程的數(shù)據(jù)交互簡(jiǎn)單職責(zé)明確珊佣,父線程只需要接收新連接,子線程完成后續(xù)的業(yè)務(wù)處理
  • 父線程與子線程的數(shù)據(jù)交互簡(jiǎn)單披粟,Reactor主線程只需要把新連接傳給子線程,子線程無(wú)需返回?cái)?shù)據(jù)

這種模型在許多項(xiàng)目中廣泛使用冷冗,包括Nginx主從Reactor多進(jìn)程模型守屉,Memcached主從多線程,Netty主從多線程模型的支持

3.2.4 總結(jié)

3種模式可以用個(gè)比喻來(lái)理解:
餐廳常常雇傭接待員負(fù)責(zé)迎接顧客蒿辙,當(dāng)顧客入坐后拇泛,侍應(yīng)生專門為這張桌子服務(wù)

  • 單Reactor單線程
    接待員和侍應(yīng)生是同一個(gè)人滨巴,全程為顧客服務(wù)
  • 單Reactor多線程
    1個(gè)接待員,多個(gè)侍應(yīng)生俺叭,接待員只負(fù)責(zé)接待
  • 主從Reactor多線程
    多個(gè)接待員恭取,多個(gè)侍應(yīng)生

Reactor模式具有如下的優(yōu)點(diǎn):

  • 響應(yīng)快,不必為單個(gè)同步時(shí)間所阻塞熄守,雖然Reactor本身依然是同步的
  • 編程相對(duì)簡(jiǎn)單蜈垮,可以最大程度的避免復(fù)雜的多線程及同步問(wèn)題,并且避免了多線程/進(jìn)程的切換開(kāi)銷裕照;
  • 可擴(kuò)展性攒发,可以方便的通過(guò)增加Reactor實(shí)例個(gè)數(shù)來(lái)充分利用CPU資源
  • 可復(fù)用性,Reactor模型本身與具體事件處理邏輯無(wú)關(guān)晋南,具有很高的復(fù)用性

3.3 Proactor模型

在Reactor模式中惠猿,Reactor等待某個(gè)事件或者可應(yīng)用或個(gè)操作的狀態(tài)發(fā)生(比如文件描述符可讀寫(xiě),或者是socket可讀寫(xiě))负间,然后把這個(gè)事件傳給事先注冊(cè)的Handler(事件處理函數(shù)或者回調(diào)函數(shù))偶妖,由后者來(lái)做實(shí)際的讀寫(xiě)操作,其中的讀寫(xiě)操作都需要應(yīng)用程序同步操作政溃,所以Reactor是非阻塞同步網(wǎng)絡(luò)模型趾访。如果把I/O操作改為異步,即交給操作系統(tǒng)來(lái)完成就能進(jìn)一步提升性能玩祟,這就是異步網(wǎng)絡(luò)模型Proactor

Proactor

Proactor是和異步I/O相關(guān)的腹缩,詳細(xì)方案如下:

  • ProactorInitiator創(chuàng)建Proactor和Handler對(duì)象,并將Proactor和Handler都通過(guò)AsyOptProcessor(Asynchronous Operation Processor)注冊(cè)到內(nèi)核
  • AsyOptProcessor處理注冊(cè)請(qǐng)求空扎,并處理I/O操作
  • AsyOptProcessor完成I/O操作后通知Proactor
  • Proactor根據(jù)不同的事件類型回調(diào)不同的Handler進(jìn)行業(yè)務(wù)處理
  • Handler完成業(yè)務(wù)處理

可以看出Proactor和Reactor的區(qū)別:Reactor是在事件發(fā)生時(shí)就通知事先注冊(cè)的事件(讀寫(xiě)在應(yīng)用程序線程中處理完成)藏鹊;Proactor是在事件發(fā)生時(shí)基于異步I/O完成讀寫(xiě)操作(由內(nèi)核完成),待I/O操作完成后才回調(diào)應(yīng)用程序的處理器來(lái)處理進(jìn)行業(yè)務(wù)處理

理論上Proactor比Reactor效率更高转锈,異步I/O更加充分發(fā)揮DMA(Direct Memory Access盘寡,直接內(nèi)存存取)的優(yōu)勢(shì),但是有如下缺點(diǎn):

  • 編程復(fù)雜性
    由于異步操作流程的事件的初始化和事件完成在時(shí)間和空間上都是相互分離的撮慨,因此開(kāi)發(fā)異步應(yīng)用程序更加復(fù)雜竿痰。應(yīng)用程序還可能因?yàn)榉聪虻牧骺囟兊酶与y以Debug
  • 內(nèi)存使用
    緩沖區(qū)在讀或?qū)懖僮鞯臅r(shí)間段內(nèi)必須保持住,可能造成持續(xù)的不確定性砌溺,并且每個(gè)并發(fā)操作都要求有獨(dú)立的緩存影涉,相比Reactor模式,在socket已經(jīng)準(zhǔn)備好讀或?qū)懬肮娣ィ遣灰箝_(kāi)辟緩存的
  • 操作系統(tǒng)支持
    Windows 下通過(guò) IOCP 實(shí)現(xiàn)了真正的異步 I/O蟹倾,而在 Linux 系統(tǒng)下,Linux2.6才引入,目前異步I/O還不完善

因此在Linux下實(shí)現(xiàn)高并發(fā)網(wǎng)絡(luò)編程都是以Reactor模型為主

參考

從0開(kāi)始學(xué)架構(gòu) —— Alibaba技術(shù)專家李運(yùn)華

Netty入門與實(shí)戰(zhàn)

技術(shù): Linux網(wǎng)絡(luò)IO模型

多線程網(wǎng)絡(luò)服務(wù)模型

IO中的阻塞鲜棠、非阻塞肌厨、同步、異步

UNIX網(wǎng)絡(luò)編程卷1:套接字聯(lián)網(wǎng)API(第3版)

異步網(wǎng)絡(luò)模型

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末豁陆,一起剝皮案震驚了整個(gè)濱河市柑爸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盒音,老刑警劉巖表鳍,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異里逆,居然都是意外死亡进胯,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門原押,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)振诬,“玉大人参袱,你說(shuō)我怎么就攤上這事掺喻〖牵” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵笨农,是天一觀的道長(zhǎng)就缆。 經(jīng)常有香客問(wèn)我,道長(zhǎng)谒亦,這世上最難降的妖魔是什么竭宰? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮份招,結(jié)果婚禮上切揭,老公的妹妹穿的比我還像新娘。我一直安慰自己锁摔,他們只是感情好廓旬,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著谐腰,像睡著了一般孕豹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上十气,一...
    開(kāi)封第一講書(shū)人閱讀 50,084評(píng)論 1 291
  • 那天励背,我揣著相機(jī)與錄音,去河邊找鬼砸西。 笑死椅野,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播竟闪,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼杖狼!你這毒婦竟也來(lái)了炼蛤?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蝶涩,失蹤者是張志新(化名)和其女友劉穎理朋,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體绿聘,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嗽上,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了熄攘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兽愤。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖挪圾,靈堂內(nèi)的尸體忽然破棺而出浅萧,到底是詐尸還是另有隱情,我是刑警寧澤哲思,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布洼畅,位于F島的核電站,受9級(jí)特大地震影響棚赔,放射性物質(zhì)發(fā)生泄漏帝簇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一靠益、第九天 我趴在偏房一處隱蔽的房頂上張望丧肴。 院中可真熱鬧,春花似錦捆毫、人聲如沸闪湾。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)途样。三九已至,卻和暖如春濒憋,著一層夾襖步出監(jiān)牢的瞬間何暇,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工凛驮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留裆站,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像宏胯,于是被迫代替她去往敵國(guó)和親羽嫡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 本文基于Netty4.1展開(kāi)介紹相關(guān)理論模型肩袍,使用場(chǎng)景杭棵,基本組件、整體架構(gòu)氛赐,知其然且知其所以然魂爪,希望給讀者提供學(xué)習(xí)...
    caison閱讀 2,899評(píng)論 0 13
  • Netty的簡(jiǎn)單介紹 Netty 是一個(gè) NIO client-server(客戶端服務(wù)器)框架,使用 Netty...
    AI喬治閱讀 8,396評(píng)論 1 101
  • 遇到的每一個(gè)人 可能是你的命中注定 也可能是你的命中不幸
    阿徐阿徐不靜閱讀 144評(píng)論 0 0
  • 倘若早知道結(jié)局是如此,你還會(huì)不會(huì)如飛蛾一樣牲芋,撲火得忘乎所以撩笆? 《最好的我們》里最令人心疼的就是簡(jiǎn)單和路星河了吧?一...
    二姑娘兒閱讀 769評(píng)論 0 4