高效能網路程式設計-反應堆模型(reactor)

朱超迪發表於2016-09-13

reactor反應堆模式


對反應堆構架模式的分析,我們使用參考文獻的分析風格,著重分析意圖、上下 文、問題、解決方案、結構和實現 6個方面的內容。


意圖

在事件驅動的應用中,將一個或多個客戶的服務請求分離(demultiplex)和事件分發器 (dispatch)給應用程式。

上下文

在事件驅動的應用中,同步地、有序地處理同時接收的多個服務請求。

問題

在分散式系統尤其是伺服器這一類事件驅動應用中,雖然這些請求最終會被序列化地處理,但是必須時刻準備著處理多個同時到來的服務請求。在實際應用中,這些請求總是通過一個事件(如CONNECTOR、READ、WRITE等)來表示的。在有 序地處理這些服務請求之前,應用程式必須先分離和排程這些同時到達的事件。為了有效地解決這個問題,我們需要做到以下4方面:
為了提高系統的可測量性和反應時間,應用程式不能長時間阻塞在某個事件源上而停止對其他事件的處理,這樣會嚴重降低對客戶端的響應度。
為了提高吞吐量,任何沒有必要的上下文切換、同步和CPU之間的資料移動都要避免。
引進新的服務或 改良已有的服務都要對既有的事件分離和排程機制帶來儘可能小的影響。
大量的應用程式程式碼需要隱藏在複雜的多執行緒和同步機制之後。

解決方案

在一個或多個事件源上等待事件的到來,例如,一個已經連線的Socket描述符就是一個事件源。將事件的分離和排程整合到處理它的服務中,而將分離和排程機制從應用程式對特定事件的處理中分離開,也就是說分離和排程機制與特定的應用程式無關。
具體來說,每個應用程式提供的每個服務都有一個獨立的事件處理器與之對應。由 事件處理器處理來自事件源的特定型別的事件。每個事件處理器都事先註冊到Reactor管理器中。Reactor管理器使用同步事件分離器在一個或多個事件源中等待事件的發生。當事件發生後,同步事件分離器通知Reactor管理器,最後由Reactor管理器排程和該事件相關的事件處理器來完成請求的服務。

結構

在Reactor模式中,有5個關鍵的參與者。


描述符(handle):

由作業系統提供,用於識別每一個事件,如Socket描述符、文 件描述符等。在Linux中,它用一個整數來表示。事件可以來自外部,如來自客戶端 的連線請求、資料等。事件也可以來自內部,如定時器事件。


同步事件分離器 (demultiplexer):

是一個函式,用來等待一個或多個事件的發生。呼叫者會被阻 塞,直到分離器分離的描述符集上有事件發生。Linux的select函式是一個經常被使 用的分離器。


事件處理器介面(event handler):

是由一個或多個模板函式組成的介面。這些模板函式描述了和應用程式相關的對某個事件的操作。具體的事件處理器:是事件處理器介面的實現。它實現了應用程式提供的某個服務。每個具體的事件處理器總和一個描述符相關。它使用描述符來識別事件、識別應用程式提供的服務。


Reactor管理器(reactor):

定義了一些介面,用於應用程式控制事件排程,以及應用程式註冊、刪除事件處理器和相關的描述符。它是事件處理器的排程核心。Reactor管理器使用同步事件分離器來等待事件的發生。一旦事件發生,Reactor管理器先是分離每個事件,然後排程事件處理器,最後呼叫相關的模板函 數來處理這個事件。通過上述分析,我們注意到,是Reactor管理器而不是應用程式負責等待事件、分離事件和排程事件。實際上,Reactor管理器並沒有被具體的事件處理器呼叫,而是管理器排程具體的事件處理器,由事件處理器對發生的事件做出處理。這就是類似Hollywood原則的“反向控制”。應用程式要做的僅僅是實現一個具體的事件處理器,然後把它註冊到Reactor管理器中。接下來的工作由管理 器來完成。這些參與者的相互關係如圖2-1所示。

這裡寫圖片描述

注意:這裡提及的反應堆模型,實際上就是外國人設計的一個概念,將我們從程式導向程式設計轉換為一個物件導向程式設計的一個東西,我們可以簡單的認為,直接操作IO模型,是一個程式導向的操作,而由一個反應堆來操作的,是一個物件導向的操作,期間,面相物件操作會提高部分效能。

相關文章