日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
如何理解高性能網(wǎng)絡(luò)模型?這篇文章說透了

【稿件】本文旨在為大家提供有用的概覽以及網(wǎng)絡(luò)服務(wù)模型的比較,以揭開設(shè)計和實現(xiàn)高性能網(wǎng)絡(luò)架構(gòu)的神秘面紗。

目前成都創(chuàng)新互聯(lián)已為上千余家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬主機、網(wǎng)站托管維護、企業(yè)網(wǎng)站設(shè)計、彌渡網(wǎng)站維護等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

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

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

由上圖可以看到,主要處理步驟包括: 

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

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

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

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

I/O 模型

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

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

兩者的***區(qū)別在于被調(diào)用方在收到請求到返回結(jié)果之前的這段時間內(nèi),調(diào)用方是否一直在等待。

阻塞是指調(diào)用方一直在等待而且別的事情什么都不做;非阻塞是指調(diào)用方先去忙別的事情。

同步處理與異步處理

同步處理是指被調(diào)用方得到最終結(jié)果之后才返回給調(diào)用方;異步處理是指被調(diào)用方先返回應(yīng)答,然后再計算調(diào)用結(jié)果,計算完最終結(jié)果后再通知并返回給調(diào)用方。

阻塞、非阻塞和同步、異步的區(qū)別

  • 阻塞、非阻塞和同步、異步其實針對的對象是不一樣的:
  • 阻塞、非阻塞的討論對象是調(diào)用者。

同步、異步的討論對象是被調(diào)用者。

recvfrom 函數(shù)

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

一個輸入操作通常包括兩個不同的階段:

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

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

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

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

在阻塞式 I/O 模型中,應(yīng)用程序在從調(diào)用 recvfrom 開始到它返回有數(shù)據(jù)報準備好這段時間是阻塞的,recvfrom 返回成功后,應(yīng)用進程開始處理數(shù)據(jù)報。

比喻:一個人在釣魚,當沒魚上鉤時,就坐在岸邊一直等。

優(yōu)點:程序簡單,在阻塞等待數(shù)據(jù)期間進程/線程掛起,基本不會占用 CPU 資源。

缺點:每個連接需要獨立的進程/線程單獨處理,當并發(fā)請求量大時為了維護程序,內(nèi)存、線程切換開銷較大,這種模型在實際生產(chǎn)中很少使用。

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

在非阻塞式 I/O 模型中,應(yīng)用程序把一個套接口設(shè)置為非阻塞,就是告訴內(nèi)核,當所請求的 I/O 操作無法完成時,不要將進程睡眠。

而是返回一個錯誤,應(yīng)用程序基于 I/O 操作函數(shù)將不斷的輪詢數(shù)據(jù)是否已經(jīng)準備好,如果沒有準備好,繼續(xù)輪詢,直到數(shù)據(jù)準備好為止。

比喻:邊釣魚邊玩手機,隔會再看看有沒有魚上鉤,有的話就迅速拉桿。

優(yōu)點:不會阻塞在內(nèi)核的等待數(shù)據(jù)過程,每次發(fā)起的 I/O 請求可以立即返回,不用阻塞等待,實時性較好。

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

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

在 I/O 復(fù)用模型中,會用到 Select 或 Poll 函數(shù)或 Epoll 函數(shù)(Linux 2.6 以后的內(nèi)核開始支持),這兩個函數(shù)也會使進程阻塞,但是和阻塞 I/O 有所不同。

這兩個函數(shù)可以同時阻塞多個 I/O 操作,而且可以同時對多個讀操作,多個寫操作的 I/O 函數(shù)進行檢測,直到有數(shù)據(jù)可讀或可寫時,才真正調(diào)用 I/O 操作函數(shù)。

比喻:放了一堆魚竿,在岸邊一直守著這堆魚竿,沒魚上鉤就玩手機。

優(yōu)點:可以基于一個阻塞對象,同時在多個描述符上等待就緒,而不是使用多個線程(每個文件描述符一個線程),這樣可以大大節(jié)省系統(tǒng)資源。

缺點:當連接數(shù)較少時效率相比多線程+阻塞 I/O 模型效率較低,可能延遲更大,因為單個連接處理需要 2 次系統(tǒng)調(diào)用,占用時間會有增加。

信號驅(qū)動式 I/O 模型(signal-driven I/O)

在信號驅(qū)動式 I/O 模型中,應(yīng)用程序使用套接口進行信號驅(qū)動 I/O,并安裝一個信號處理函數(shù),進程繼續(xù)運行并不阻塞。

當數(shù)據(jù)準備好時,進程會收到一個 SIGIO 信號,可以在信號處理函數(shù)中調(diào)用 I/O 操作函數(shù)處理數(shù)據(jù)。

比喻:魚竿上系了個鈴鐺,當鈴鐺響,就知道魚上鉤,然后可以專心玩手機。

優(yōu)點:線程并沒有在等待數(shù)據(jù)時被阻塞,可以提高資源的利用率。

缺點:信號 I/O 在大量 IO 操作時可能會因為信號隊列溢出導(dǎo)致沒法通知。

信號驅(qū)動 I/O 盡管對于處理 UDP 套接字來說有用,即這種信號通知意味著到達一個數(shù)據(jù)報,或者返回一個異步錯誤。

但是,對于 TCP 而言,信號驅(qū)動的 I/O 方式近乎無用,因為導(dǎo)致這種通知的條件為數(shù)眾多,每一個來進行判別會消耗很大資源,與前幾種方式相比優(yōu)勢盡失。

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

由 POSIX 規(guī)范定義,應(yīng)用程序告知內(nèi)核啟動某個操作,并讓內(nèi)核在整個操作(包括將數(shù)據(jù)從內(nèi)核拷貝到應(yīng)用程序的緩沖區(qū))完成后通知應(yīng)用程序。

這種模型與信號驅(qū)動模型的主要區(qū)別在于:信號驅(qū)動 I/O 是由內(nèi)核通知應(yīng)用程序何時啟動一個 I/O 操作,而異步 I/O 模型是由內(nèi)核通知應(yīng)用程序 I/O 操作何時完成。

優(yōu)點:異步 I/O 能夠充分利用 DMA 特性,讓 I/O 操作與計算重疊。

缺點:要實現(xiàn)真正的異步 I/O,操作系統(tǒng)需要做大量的工作。目前 Windows 下通過 IOCP 實現(xiàn)了真正的異步 I/O。

而在 Linux 系統(tǒng)下,Linux 2.6才引入,目前 AIO 并不完善,因此在 Linux 下實現(xiàn)高并發(fā)網(wǎng)絡(luò)編程時都是以 IO 復(fù)用模型模式為主。

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

從上圖中我們可以看出,越往后,阻塞越少,理論上效率也是***。

這五種 I/O 模型中,前四種屬于同步 I/O,因為其中真正的 I/O 操作(recvfrom)將阻塞進程/線程,只有異步 I/O 模型才與 POSIX 定義的異步 I/O 相匹配。

線程模型

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

值得說明的是,具體選擇線程還是進程,更多是與平臺及編程語言相關(guān)。

例如 C 語言使用線程和進程都可以(例如 Nginx 使用進程,Memcached 使用線程),Java 語言一般使用線程(例如 Netty),為了描述方便,下面都使用線程來進行描述。

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

特點:

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

存在問題:

  • 當并發(fā)數(shù)較大時,需要創(chuàng)建大量線程來處理連接,系統(tǒng)資源占用較大。
  • 連接建立后,如果當前線程暫時沒有數(shù)據(jù)可讀,則線程就阻塞在 Read 操作上,造成線程資源浪費。

Reactor 模式

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

  • 基于 I/O 復(fù)用模型,多個連接共用一個阻塞對象,應(yīng)用程序只需要在一個阻塞對象上等待,無需阻塞等待所有連接。

當某條連接有新的數(shù)據(jù)可以處理時,操作系統(tǒng)通知應(yīng)用程序,線程從阻塞狀態(tài)返回,開始進行業(yè)務(wù)處理。

  • 基于線程池復(fù)用線程資源,不必再為每個連接創(chuàng)建線程,將連接完成后的業(yè)務(wù)處理任務(wù)分配給線程進行處理,一個線程可以處理多個連接的業(yè)務(wù)。

I/O 復(fù)用結(jié)合線程池,這就是 Reactor 模式基本設(shè)計思想,如下圖:

Reactor 模式,是指通過一個或多個輸入同時傳遞給服務(wù)處理器的服務(wù)請求的事件驅(qū)動處理模式。 

服務(wù)端程序處理傳入多路請求,并將它們同步分派給請求對應(yīng)的處理線程,Reactor 模式也叫 Dispatcher 模式。

即 I/O 多了復(fù)用統(tǒng)一監(jiān)聽事件,收到事件后分發(fā)(Dispatch 給某進程),是編寫高性能網(wǎng)絡(luò)服務(wù)器的必備技術(shù)之一。

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

  • Reactor,Reactor 在一個單獨的線程中運行,負責(zé)監(jiān)聽和分發(fā)事件,分發(fā)給適當?shù)奶幚沓绦騺韺?IO 事件做出反應(yīng)。 它就像公司的電話接線員,它接聽來自客戶的電話并將線路轉(zhuǎn)移到適當?shù)穆?lián)系人。
  • Handlers,處理程序執(zhí)行 I/O 事件要完成的實際事件,類似于客戶想要與之交談的公司中的實際官員。Reactor 通過調(diào)度適當?shù)奶幚沓绦騺眄憫?yīng) I/O 事件,處理程序執(zhí)行非阻塞操作。

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

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

下面詳細介紹這 3 種實現(xiàn)方式。

單 Reactor 單線程

其中,Select 是前面 I/O 復(fù)用模型介紹的標準網(wǎng)絡(luò)編程 API,可以實現(xiàn)應(yīng)用程序通過一個阻塞對象監(jiān)聽多路連接請求,其他方案示意圖類似。

方案說明:

Reactor 對象通過 Select 監(jiān)控客戶端請求事件,收到事件后通過 Dispatch 進行分發(fā)。

  • 如果是建立連接請求事件,則由 Acceptor 通過 Accept 處理連接請求,然后創(chuàng)建一個 Handler 對象處理連接完成后的后續(xù)業(yè)務(wù)處理。
  • 如果不是建立連接事件,則 Reactor 會分發(fā)調(diào)用連接對應(yīng)的 Handler 來響應(yīng)。
  • Handler 會完成 Read→業(yè)務(wù)處理→Send 的完整業(yè)務(wù)流程。

優(yōu)點:模型簡單,沒有多線程、進程通信、競爭的問題,全部都在一個線程中完成。

缺點:性能問題,只有一個線程,無法完全發(fā)揮多核 CPU 的性能。Handler 在處理某個連接上的業(yè)務(wù)時,整個進程無法處理其他連接事件,很容易導(dǎo)致性能瓶頸。

可靠性問題,線程意外跑飛,或者進入死循環(huán),會導(dǎo)致整個系統(tǒng)通信模塊不可用,不能接收和處理外部消息,造成節(jié)點故障。

使用場景:客戶端的數(shù)量有限,業(yè)務(wù)處理非??焖?,比如 Redis,業(yè)務(wù)處理的時間復(fù)雜度 O(1)。

單 Reactor 多線程

方案說明:

  • Reactor 對象通過 Select 監(jiān)控客戶端請求事件,收到事件后通過 Dispatch 進行分發(fā)。
  • 如果是建立連接請求事件,則由 Acceptor 通過 Accept 處理連接請求,然后創(chuàng)建一個 Handler 對象處理連接完成后續(xù)的各種事件。
  • 如果不是建立連接事件,則 Reactor 會分發(fā)調(diào)用連接對應(yīng)的 Handler 來響應(yīng)。
  • Handler 只負責(zé)響應(yīng)事件,不做具體業(yè)務(wù)處理,通過 Read 讀取數(shù)據(jù)后,會分發(fā)給后面的 Worker 線程池進行業(yè)務(wù)處理。
  • Worker 線程池會分配獨立的線程完成真正的業(yè)務(wù)處理,如何將響應(yīng)結(jié)果發(fā)給 Handler 進行處理。
  • Handler 收到響應(yīng)結(jié)果后通過 Send 將響應(yīng)結(jié)果返回給 Client。

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

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

主從 Reactor 多線程

針對單 Reactor 多線程模型中,Reactor 在單線程中運行,高并發(fā)場景下容易成為性能瓶頸,可以讓 Reactor 在多線程中運行。

方案說明:

  • Reactor 主線程 MainReactor 對象通過 Select 監(jiān)控建立連接事件,收到事件后通過 Acceptor 接收,處理建立連接事件。
  • Acceptor 處理建立連接事件后,MainReactor 將連接分配 Reactor 子線程給 SubReactor 進行處理。
  • SubReactor 將連接加入連接隊列進行監(jiān)聽,并創(chuàng)建一個 Handler 用于處理各種連接事件。
  • 當有新的事件發(fā)生時,SubReactor 會調(diào)用連接對應(yīng)的 Handler 進行響應(yīng)。
  • Handler 通過 Read 讀取數(shù)據(jù)后,會分發(fā)給后面的 Worker 線程池進行業(yè)務(wù)處理。
  • Worker 線程池會分配獨立的線程完成真正的業(yè)務(wù)處理,如何將響應(yīng)結(jié)果發(fā)給 Handler 進行處理。
  • Handler 收到響應(yīng)結(jié)果后通過 Send 將響應(yīng)結(jié)果返回給 Client。

優(yōu)點:父線程與子線程的數(shù)據(jù)交互簡單職責(zé)明確,父線程只需要接收新連接,子線程完成后續(xù)的業(yè)務(wù)處理。

父線程與子線程的數(shù)據(jù)交互簡單,Reactor 主線程只需要把新連接傳給子線程,子線程無需返回數(shù)據(jù)。

這種模型在許多項目中廣泛使用,包括 Nginx 主從 Reactor 多進程模型,Memcached 主從多線程,Netty 主從多線程模型的支持。

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

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

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

  • 響應(yīng)快,不必為單個同步時間所阻塞,雖然 Reactor 本身依然是同步的。
  • 編程相對簡單,可以***程度的避免復(fù)雜的多線程及同步問題,并且避免了多線程/進程的切換開銷。
  • 可擴展性,可以方便的通過增加 Reactor 實例個數(shù)來充分利用 CPU 資源。
  • 可復(fù)用性,Reactor 模型本身與具體事件處理邏輯無關(guān),具有很高的復(fù)用性。

Proactor 模型

在 Reactor 模式中,Reactor 等待某個事件或者可應(yīng)用或者操作的狀態(tài)發(fā)生(比如文件描述符可讀寫,或者是 Socket 可讀寫)。

然后把這個事件傳給事先注冊的 Handler(事件處理函數(shù)或者回調(diào)函數(shù)),由后者來做實際的讀寫操作。

其中的讀寫操作都需要應(yīng)用程序同步操作,所以 Reactor 是非阻塞同步網(wǎng)絡(luò)模型。

如果把 I/O 操作改為異步,即交給操作系統(tǒng)來完成就能進一步提升性能,這就是異步網(wǎng)絡(luò)模型 Proactor。

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

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

可以看出 Proactor 和 Reactor 的區(qū)別:

  • Reactor 是在事件發(fā)生時就通知事先注冊的事件(讀寫在應(yīng)用程序線程中處理完成)。
  • Proactor 是在事件發(fā)生時基于異步 I/O 完成讀寫操作(由內(nèi)核完成),待 I/O 操作完成后才回調(diào)應(yīng)用程序的處理器來進行業(yè)務(wù)處理。

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

  • 編程復(fù)雜性,由于異步操作流程的事件的初始化和事件完成在時間和空間上都是相互分離的,因此開發(fā)異步應(yīng)用程序更加復(fù)雜。應(yīng)用程序還可能因為反向的流控而變得更加難以 Debug。
  • 內(nèi)存使用,緩沖區(qū)在讀或?qū)懖僮鞯臅r間段內(nèi)必須保持住,可能造成持續(xù)的不確定性,并且每個并發(fā)操作都要求有獨立的緩存,相比 Reactor 模式,在 Socket 已經(jīng)準備好讀或?qū)懬?,是不要求開辟緩存的。
  • 操作系統(tǒng)支持,Windows 下通過 IOCP 實現(xiàn)了真正的異步 I/O,而在 Linux 系統(tǒng)下,Linux 2.6 才引入,目前異步 I/O 還不完善。

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

參考文章:

  • 從 0 開始學(xué)架構(gòu) —— Alibaba 技術(shù)專家李運華
  • 技術(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ò)模型

陳彩華(caison),主要從事服務(wù)端開發(fā)、需求分析、系統(tǒng)設(shè)計、優(yōu)化重構(gòu)工作,主要開發(fā)語言是 Java,現(xiàn)任廣州貝聊服務(wù)端研發(fā)工程師。微信號:hua1881375。

【原創(chuàng)稿件,合作站點轉(zhuǎn)載請注明原文作者和出處為.com】


名稱欄目:如何理解高性能網(wǎng)絡(luò)模型?這篇文章說透了
網(wǎng)站URL:http://m.5511xx.com/article/cojhceg.html