天天看點

JavaSocket程式設計之Netty架構線程模型

1.Netty概述

    Netty是一個由JBoss提供的高效的Java NIO client-server(用戶端-伺服器)開發架構,使用Netty可以快速開發網絡應用。Netty提供了一種新的方式來使開發網絡應用程式,使其很容易使用且有很強的可擴充性。Netty的内部實作是很複雜的,但是Netty提供了簡單易用的API從網絡處理代碼中解耦業務邏輯。Netty是完全基于NIO實作的,采用事件驅動機制,非阻塞執行,是以整個Netty都是異步的。Netty架構體系結構圖如下:

JavaSocket程式設計之Netty架構線程模型

2.Java NIO緩沖區與通道

    一個Buffer對象是固定數量的資料的容器,其作用是一個存儲器。通道Channel是I/O傳輸發生時通過的入口,而緩沖區是這些資料傳輸的來源或目标。對于離開緩沖區的傳輸,您想傳遞出去的資料被置于一個緩沖區,被傳送到通道。緩沖區是包在一個對象内的基本資料元素數組。Buffer類相比一個簡單數組的優點是它将關于資料的資料内容和資訊包含在一個單一的對象中。緩沖區家族成員如下所示:

JavaSocket程式設計之Netty架構線程模型

緩沖區Buffer具有四個屬性來提供關于其所包含的資料元素的資訊。

它們是:

容量(Capacity)緩沖區能夠容納的資料元素的最大數量。這一容量在緩沖區建立時被設定,且不能被改變。

上界(Limit)緩沖區的第一個不能被讀或寫的元素。或者說,緩沖區中現存元素的計數。

位置(Position)下一個要被讀或寫的元素的索引。位置會自動由相應的get( )和put( )函數更新。

标記(Mark)一個備忘位置。調用mark( )來設定mark = postion。調用reset( )設定position = mark。标記在設定前是未定義的(undefined)。

這四個屬性之間總是遵循以下關系

0 <= mark <= position <= limit <= capacity

JavaSocket程式設計之Netty架構線程模型

3.Netty核心網絡模型

   Netty是典型的Reactor模型結構,在實作上,Netty中的Boss類充當mainReactor,NioWorker類充當subReactor(預設NioWorker的個數是目前伺服器的可用核數)。在處理新來的請求時,NioWorker讀完已收到的資料到ChannelBuffer中,之後觸發ChannelPipeline中的ChannelHandler流。Netty是事件驅動,非阻塞的,可以通過ChannelHandler鍊來控制執行流向。

3.1 Refactor單線程模型 

  Reactor單線程模型,指的是所有的IO操作都在同一個NIO線程上面完成;

Reactor單線程模型特點:

1)Java NIO服務端,接收用戶端的TCP連接配接;

2)Java NIO用戶端,向服務端發起TCP連接配接;

3)Java NIO服務端/用戶端,讀取通信對端的請求或者應答消息;

4)Java NIO服務端/用戶端,向通信對端發送消息請求或者應答消息

使用場景:對于一些小容量應用場景,可以使用單線程模型。但是對于高負載、大并發的應用場景卻不合适,比如一個NIO線程同時處理成百上千的鍊路,性能上無法支撐,即便NIO線程的CPU負荷達到100%,也無法滿足海量消息的編碼、解碼、讀取和發送。Reactor單線程模型如下圖所示:

JavaSocket程式設計之Netty架構線程模型

3.2 Refactor多線程模型  

Rector多線程模型與單線程模型最大的差別就是有一組NIO線程處理IO操作。

Reactor多線程模型的特點:

1)有一個專門的NIO線程-Acceptor線程用于監聽服務端,接收用戶端的TCP連接配接請求;

2)網絡IO操作-讀、寫等由一個NIO線程池負責,線程池可以采用标準的JDK線程池實作,它包含一個任務隊列和N個可用的線程,由這些NIO線程負責消息的讀取、解碼、編碼和發送;

3)1個NIO線程可以同時處理N條鍊路,但是1個鍊路隻對應1個NIO線程,防止發生并發操作問題。

Reactor多線程模型如下圖所示:

JavaSocket程式設計之Netty架構線程模型

3.3 Netty伺服器端建立過程

Netty伺服器啟動時,建立兩個NIOEventLoopGroup獨立的Reator線程池,一個用于接收用戶端的TCP連接配接,一個用于處理IO的相關的讀寫操作。

Netty線程模型是建立在Reactor模型的基礎上,線程模型并不是一成不變的,通過啟動參數的配置,可以在不同的線程模型之間切換。

Netty伺服器端建立過程式列圖如下:

JavaSocket程式設計之Netty架構線程模型

1)首先建立一個ServerBootstrap執行個體,這是Netty服務端的啟動輔助類;

2)設定并綁定Reactor線程池,Netty的Reactor線程池是EventLoopGroup,它其實就是EventLoop線程的數組。EventLoop的職責是處理所有注冊到本線程多路複用器Selector上的Channel;

3)設定并綁定服務端NIOserverSocketChannel, Netty通過工廠類,利用反射方式建立NioServerSocketChannel對象

4)設定TCP連接配接參數,TCP鍊路建立時建立并初始化ChannelPipeline,它本質是一個負責處理網絡事件的職責鍊,負責管理和執行ChannelHandler。網絡事件以事件流的形式在ChannelPipeline中流轉,由ChannelPipeline根據ChannelHandler的執行政策排程ChannelHandler的執行;

5)添加并設定ChannelHandler,加入到ChannelPipeline事件流;

6)伺服器端綁定監聽端口,并啟動伺服器;

7)啟動NioEventLoop負責排程和執行Selector輪詢操作,選擇準備就緒的Channel集合;

8)當輪詢到準備就緒的Channel之後,就由Reactor線程NioEventLoop執行ChannelPipeline的相應方法;

9)執行Netty系統并排程執行ChannelHandler業務邏輯

3.4Netty線程模型執行個體

    注冊兩個OutboundHandler,執行順序為注冊順序的逆序,注冊兩個InboundHandler,執行順序為注冊順序,注冊HelloServerInHandler用于接收用戶端消息已經向用戶端發送消息,主要代碼如下:

JavaSocket程式設計之Netty架構線程模型
JavaSocket程式設計之Netty架構線程模型

本訂閱号提供Java相關技術分享,從Java程式設計基礎到Java進階技術,從JavaWeb技術基礎Jsp、Servlet、JDBC到SSH、SSM開發架構,從REST風格接口設計到分布式項目實戰。剖析主流開源技術架構,用親身實踐來譜寫深度Java技術日志。

JavaSocket程式設計之Netty架構線程模型

Java技術日志

微信掃描二維碼,關注Java技術日志