【IO專欄】單線程Reactor反應器模式

總體來說,Reactor反應器模式有點類似事件驅動模式。

在事件驅動模式中,當有事件觸發時,事件源會將事件dispatch分發到handler處理器進行事件處理。反應器模式中的反應器角色,類似於事件驅動模式中的dispatch事件分發器的角色。

在反應器模式中有Reactor反應器和Handler處理器連個重要的組件:

(1)Reactor反應器:負責查詢IO事件,當檢測到一個IO事件,將其發送給相應的Handler處理器去處理。這裏的IO事件,就是NIO中選擇器監控的通道IO事件。

(2)Handler處理器:與IO事件(或者選擇鍵)綁定,負責IO事件的處理。完成真正的鏈接建立,通道讀取,處理業務邏輯,負責將結果寫出到通道等。

 

單線程反應器?

什麼是單線程版本的Reactor反應器模式呢?簡單來說,Reactor反應器和Handler處理器處於一個線程中執行。它是最簡單的反應器模式。

基於Java NIO,如何實現簡單的單線程版本的反應器模式呢?需要用到SelectionKey選擇鍵的幾個重要的成員方法:

方法一:void attach(Object o);

此方法可以將任何的JAVA POJO對象,作爲附件添加到SelectionKey實例,相當於附件屬性的setter方法。這方法非常重要,因爲在單線程版本的反應器中,需要將Handler處理器實例,作爲附件添加到SelectionKey實例。

方法二:Object attachment();

此方法的作用是去處之前通過attach(Object o)添加到SelectKey選擇鍵實例的附件,相當於附件屬性的getter方法,與attach(Object o)配套使用。

這個方法同樣非常重要,當IO事件發生,選擇鍵被select方法選到,可以直接將事件的附件取出來,也就是之前綁定的Handler處理器實例,通過該Handler,完成相應的處理。

總之,在反應器模式中,需要進行attach和attachent結合使用:在選擇鍵註冊完成之後,調用attach方法,將Hannder處理器綁定到選擇鍵;當事件發生時,調用attachment方法,可以從選擇鍵出去Handler處理器,將事件分發到Handler處理器中,完成業務處理。

 

單線程Reactor反應器的缺點

單線程Reactor反應器模式,是基於Java的NIO實現的。相對於傳統的多線程OIO,反應器模式不再需要啓動成千上萬條線程,效率自然是大大的提升了。

在單線程反應器中,Reactor反應器和Handler處理器,都執行在同一個線程上。這樣,帶來了一個問題:當其中某個Handler阻塞時,會導致其他所有的Handler都得不到執行。在這種場景下,如果被阻塞的Handler不僅僅負責輸入和輸出業務,還包括負責連接監聽的AcceptorHandler處理器。這個是非常嚴重的問題。

爲什麼呢?一旦一AcceptorHandler處理器阻塞,會導致整個服務不能接收新的連接,使得服務器變的不可用。因爲這個缺陷,因此單線程反應器模型用的比較少。

另外,目前的服務器都是多核的,單線程反應器模式模型不能充分利用多核資源。總之,在高性能服務器應用場景中,單線程反應器模式實際使用的很少。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章