1. 程式人生 > >Java程式設計師不能不知的兩種伺服器設計模型

Java程式設計師不能不知的兩種伺服器設計模型

概述:

我們在IO模型和Java網路程式設計模型中,對IO有了一定的理解。這一篇,主要講解基於事件驅動的兩種是在原來基礎上的擴充套件。在基於事件驅動的網路程式設計模型中,Reactor和Proactor模型是兩種常用的IO設計模型。

在前篇中,我們知道BIO(阻塞型IO)只有等待阻塞方法結束了,操作權才會交還給呼叫執行緒,在阻塞期間,呼叫者做不了任何操作,只能等待。在此期間呼叫者執行緒無法轉向其他能做的事,對呼叫者來講,這其實是一種浪費。在NIO(非阻塞IO)中,非阻塞IO會立刻將結果返回到呼叫者,呼叫者獲取結果無需等待。獲得的結果無非兩種:資料準備好了,你繼續表演吧;要麼資料還沒準備好,你要不再試試,或者你等會再試試。而對AIO(非同步IO),呼叫方立刻獲得返回,並且作業系統會使用另外的資源來達成此次的IO請求,並在作業系統完成資料準備後,通知呼叫者。

Java程式設計師不能不知的兩種伺服器設計模型
Reactor模式和Proactor模型

Reactor模型的中心思想採用的就是我們在IO模型和Java網路程式設計模型中所講的多路複用IO。Reactor模型主要包含以下幾個角色:

(1)Handle,也叫控制代碼,有些地方也叫描述符。如網路Socket IO中稱網路IO控制代碼或者Socket描述符,在檔案讀寫中稱檔案IO控制代碼或者檔案描述符等。

(2)Synchronous Event Demultiplexer,也稱同步事件多路分解器,用於阻塞等待發生在控制代碼集合上的一個或者多個事件,因為事件的到來是隨機不可預測的,底層要實現事件的監聽採取的是迴圈等待的策略,這種策略也叫事件迴圈。事件迴圈依賴系統呼叫,這裡的系統呼叫,指的就是select/poll/epol等底層函式。這些底層函式一旦監聽到控制代碼(或描述符)的讀就緒或者寫就緒,就會通知呼叫方進行讀寫操作。同步事件分離器依賴底層系統呼叫的實現。

(3)Event Handler, 可稱為事件處理器,不同的事件,可以有不同的處理器。通常IO框架庫會將事件處理器定義成一個模板函式,不同的事件處理器可以有不同的特性,擁有自己業務相關的實現。

(4)Reactor,也稱為反應器,反應器主要功能包括以下:註冊或者刪除應用程式所關注的事件控制代碼,執行事件迴圈監控事件的到來,當事件到達時,反應器分離事件,並通知到對應的具體的事件處理器上,由具體的事件處理器處理器呼叫相關的函式來實現資料的讀或者寫,處理完資料後,交還系統的控制權。

Java程式設計師不能不知的兩種伺服器設計模型
Reactor模型圖

整體的業務流可以概括為,首先呼叫者先向反應器註冊,其對某種具體 的IO動作感興趣,反應器會迴圈監控呼叫 者註冊的事件是否已發生(如可讀可寫等),當事件發生後,事件分解器就被喚醒,會通知到事件對應的處理器來完成 事件的讀寫,可以看出,在具體事件到達時,處理程式不是呼叫的反應器,而是通過反應器分離的事件處理器來作資料的讀或者寫,這種方式又被稱為“好萊塢法則”,類似於好萊塢大導演找演員的模型,你別來找我,等活來了我來找你吧。Reactor模型當有對應的IO完成時,回撥對應的函式來處理,這種模型本質上還是一種同步的IO模型,其底層也並沒有呼叫對應的非同步IO的函式。
Java程式設計師不能不知的兩種伺服器設計模型


Reactor模型中的事件處理器是基於模板的模型來實現的,這意味著不同的事件處理器是分離的,業務間具體低侵入性。Reactor模型的底層系統呼叫也是一個模板模型,可以用select實現,亦或epoll,但是必須滿足能監控活躍連線的功能。

Proactor與Reactor則不同,Reactor是基於同步IO模型實現的,而Proactor是基於非同步IO。

Proactor中,呼叫者會呼叫非同步操作處理器提供的非同步函式,呼叫之後, 呼叫者執行緒和非同步操作處理器會獨立執行,這依賴於作業系統對非同步IO的支援,實際的IO是由作業系統來完成 的。然後Proactor會進行事件迴圈,等待事件的到來 ,當事件分解器等待事件到來的同時,作業系統已經在同時將目標資料拷備到使用者空間,當拷備完成 後,會通知到事件分解器,事情已經搞完了,事件分解器將完成事件轉發到相應的事件處理者或者 回撥函式,呼叫 者就可以利用這些資料處理自己的業務邏輯 了。

Reactor和Proactor都是對某個具體IO事件的告知,這也就我們所說的基於事件驅動,Reactor是告知的事件已準備好,而Proactor是事件已做好。他們的業務 邏輯也很類似,都是事件分解器來負責IO的監控,並回調對應的事件處理器,不同之處在於Reactor事件告知的是已準備好,還需要進一步的從核心 空間資料拷備到使用者空間。而Proactor是資料已經準備好,呼叫 者可以直接在使用者空間使用了。

最後,如果有想要學習、或者正在學習Java的同學,可來我們的java技術學習扣qun哦:59789,1510裡面免費送java的視訊系統教程噢!