多線程Reactor模式及Netty線程模型

Netty是一款高效的NIO框架和工具,基于Java NIO實現,Java NIO的Selector給Reactor模式提供了基礎,netty結合Selector和Reactor模式實現自身高效的線程模型。本文先對Reactor模式的多線程和主從模型進行簡單介紹,而后結合netty中的幾個重要組件對netty線程模型和工作流程進行簡單分析。這里可以參看李林鋒的文章

多線程Reactor

與單線程不同的地方,在于多線程Reactor模型將監聽連接和連接的I/O操作放到了不同的線程里面,看下面的示意圖:

它的主要特點如下:

  • 有專門的Acceptor線程用于監聽、接收客戶端的連接請求
  • 網絡I/O的讀寫操作則由另外的線程池負責,包含一個任務隊列和多個線程
  • 一個NIO線程可以處理多個鏈路,但每個鏈路只對應一個線程

大部分情況下,一個線程負責監聽和處理所有的客戶端都能滿足需要,但在特殊場景下,如并發量過高,或者在連接接入的時候需要進行安全認證等問題,單個Acceptor線程不足以滿足性能,這時候就需要主從Reactor模型。

主從多線程Reactor

服務端用于接收連接的不再是一個單獨的NIO線程,而是一個獨立的線程池:

工作流程:

  • 從主線程池中選擇一個Reactor線程作為Acceptor線程,綁定監聽端口,接收客戶端連接
  • 接收到連接請求后,將其注冊到主線程其他線程上,由它們負責接入認證等工作
  • 鏈路建立完成后,就鏈路從主線程池的多路復用器上摘除,重新注冊到Sub線程池的NIO線程上,負責后續IO操作

netty的線程模型不是一成不變的,通過對啟動參數的配置,netty可以支持多種Reactor線程模型,最常用的是多線程模型。

下面說一下netty中幾個重要的組件。

Selector

Selector是Java NIO提供的多路復用器,負責配合操作系統的select/epoll操作將就緒的IO事件分離出來,落地為SelectionKey,我們可以將SelectionKey看做Reactor模式中的資源

EventLoop/EventLoopGroup

EventLoopGroup其實就是一個EventLoop線程組,netty中通常有多個EventLoop同時工作,每個EventLoop維護著一個Selector實例(類似單線程Reactor工作)。如果沒有顯式指定,默認每個EvenLoopGroup中的線程數為可用的CPU內核數*2。

通常每個netty服務端有兩個EventLoopGroup。

一個用作Acceptor線程池,負責處理客戶端的連接請求,通常一個服務端口對應一個EventLoop線程,根據實際需要配置線程組的線程數量。Acceptor線程通過不斷輪詢Selector上的Accept事件,將accept的SocketChannel交給另外一個EventLoop線程組。

另一個EventLoopGroup會根據線程組的順序next一個可用的EventLoop將這個SocketChannel注冊到其維護的Selector上,并處理其后續的I/O的事件。

ChannelPipleline

每個SocketChannel都有一個Pipleline實例,而每個Pipleline中維護了一個ChannelHandler鏈表隊列。Pipleline和ChannelHandler的關系類似servlet和filter過濾器的作用。EventLoop從Selector中分離出就緒的channel以后,會將它傳遞的消息傳輸到Pipleline中,通過ChannelHandler處理鏈進行層層處理,用戶可以在Handler中添加自己的業務邏輯。

ChannelPipleline中本身維護著兩個不可見的HeadHandler和TailHandler,head靠近網絡層,tail靠近用戶。netty中有兩類事件類型,inbound和outbound。inbound可以理解為從網絡數據外部流向內部,如讀取消息;outbound為網絡數據從內部流向外部,如寫消息。Pipleline會根據事件的類型, 自上而下或自下而上調用事件相關聯的ChannelHandler對消息進行處理。如讀取消息的時候會依次執行HeadHandler、ChannelHandler1...ChannelHandlerN、TailHandler。

寫在最后

通過以上幾個組件的作用,應該可以對netty的工作流程有個大體的認識。其實筆者接觸netty是從Vert.x開始的,netty可能更偏向網絡傳輸這個層面,一些RPC框架底層傳輸用的也是netty。

netty中還有其他要點,比如粘包拆包、緩沖區這些問題筆者還沒有認真研究過,待有時間再研究源碼吧,感嘆時間真不夠用啊!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容