Netty源碼分析系列之五:Netty多線程模型

引言

我們一直都說Netty是高性能服務器,那麼它到底爲什麼是高性能應用呢?線程模型直接影響着網絡應用的性能狀況,本文將從Netty的多線程模型出發揭開其高性能特性的神祕面紗。

多線程模型

(1)傳統IO模型的問題

·如果我們自己是Netty網絡應用的設計者,想要設計出高性能的網絡應用,首先要面對的問題就是如何解決網絡編程的性能瓶頸。那麼網絡應用的性能瓶頸是什麼呢?我們都知道傳統的網絡應用使用的是BIO模型,也就是阻塞式IO。網絡程序處理當中的read()以及write() 操作都會阻塞當前線程的。所以在傳統的IO模型當中每一個socket連接都會有單獨的線程來進行處理。
在這裏插入圖片描述
但是在當前的互聯網時代,客戶端的連接可能是百萬、千萬甚至上億級別的,服務器不可能創建這麼多的線程來處理客戶端請求。這就是傳統IO網絡連接的性能瓶頸所在。

(2)模型優化

如上一節內容所述,傳統的IO模型的性能瓶頸在於服務端需要爲每一個socket連接分配線程來滿足業務處理的需要。那麼有沒有一種方法可以不需要建立那麼多連接也可以處理客戶端的請求呢?如果要用一個線程處理多個請求,那麼BIO是無法實現的。所以我們可採用java中的NIO來完成此部分的優化操作。Netty的做法是採用Reactor模式,所謂Reactor模式就是是一個使用了同步非阻塞的I/O多路複用機制的模式。這裏不再展開說明。

Netty的世界中,EventLoopGroup是一個非常重要的核心概念。所謂EventLoopGroup就是就是EventLoop的集合,即爲事件循環。其中NioEventLoop負責輪詢多路複用器,獲取已經處於就緒狀態的通道,執行網絡的連接、客戶端請求接入、讀和寫相關操作。bossGroup 就用來處理連接請求的,而 workerGroup 是用來處理讀寫請求的。bossGroup 處理完連接請求後,會將這個連接提交給 workerGroup 來處理, workerGroup 裏面有多個 EventLoopworkerGroup 就是用來處理實際讀寫操作的。那新的連接會交給哪個 EventLoop 來處理呢?這就需要一個負載均衡算法,Netty 中使用的就是輪詢算法。Netty支持多種Reactor模式,如單線程模型、多線程模型以及主從多線程模型,用戶可以根據實際場景進行啓動參數中進行設置來切換對應的模式。

(3)代碼分析

a、單線程模型

EventLoopGroup bossGroup = new NioEventLoopGroup(1);
try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup)
             .channel(NioServerSocketChannel.class)
...
             }
...

如上代碼可知,創建了一個參數爲1的bossGroup ,該EventLoopGroup 主要用於接收客戶端的連接,即爲單線程模型。

b、多線程模型


EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
      ServerBootstrap b = new ServerBootstrap();
      b.group(bossGroup, workerGroup)
       .channel(NioServerSocketChannel.class)
...
}
...

與單線程模式不同,多線程模式創建了workerGroup 來處理IO操作,數量默認爲CPU數量的兩倍。

c、主從多線程模型
在該模型中,用於接收客戶端連接的線程不再是單一的NIO線程了,而是一個線程池。

//創建boss線程組,處理客戶端連接
EventLoopGroup bossGroup = new NioEventLoopGroup(2);
// 創建worker線程組用於SocketChannel 的數據讀寫
EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			// 創建 ServerBootstrap 對象
			ServerBootstrap b = new ServerBootstrap();
			// 設置EventLoopGroup
			b.group(bossGroup, workerGroup)
			// 設置要被實例化的爲 NioServerSocketChannel 類 
			.channel(NioServerSocketChannel.class)
			...
}
...

總結

本文主要介紹了Netty的多線程模型,它採用的是Reactor模型。處理連接請求與處理IO操作的線程隔離。基於事件輪詢監聽,不斷獲取處於就緒狀態的通道。其中Boss線程池的線程負責處理連接請求,接收到accept事件之後,將對應的socket進行封裝生成NioSocketChannel對象,並將其提交到workBoss線程池中,處理IO的read以及write事件。

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