高併發架構系列:Netty的實現原理、特點與優勢、適用場景

01

Netty介紹

高併發架構系列:Netty的實現原理、特點與優勢、適用場景

1.Netty簡介

Netty是由JBOSS提供的一個java開源框架。

Netty是一個高性能、異步事件驅動的NIO框架,它提供了對TCP、UDP和文件傳輸的支持。作為當前最流行的NIO框架,Netty在互聯網領域、大數據分佈式計算領域、遊戲行業、通信行業等獲得了廣泛的應用,一些業界著名的開源組件也基於Netty的NIO框架構建(文章尾有詳細介紹)。

2.Netty的特點

  • 高併發

Netty是一款基於NIO(Nonblocking I/O,非阻塞IO)開發的網絡通信框架,對比於BIO(Blocking I/O,阻塞IO),他的併發性能得到了很大提高 。

  • 傳輸快

Netty的傳輸快其實也是依賴了NIO的一個特性——零拷貝。

  • 封裝好

Netty封裝了NIO操作的很多細節,提供易於使用的API。

02

為什麼選擇Netty

JDK 原生也有一套網絡應用程序 API,但是存在一系列問題,主要如下:

1)NIO 的類庫和 API 繁雜,使用麻煩:你需要熟練掌握 Selector、ServerSocketChannel、SocketChannel、ByteBuffer 等。

2)需要具備其他的額外技能做鋪墊:例如熟悉 Java 多線程編程,因為 NIO 編程涉及到 Reactor 模式,你必須對多線程和網路編程非常熟悉,才能編寫出高質量的 NIO 程序。

3)可靠性能力補齊,開發工作量和難度都非常大:例如客戶端面臨斷連重連、網絡閃斷、半包讀寫、失敗緩存、網絡擁塞和異常碼流的處理等等。NIO 編程的特點是功能開發相對容易,但是可靠性能力補齊工作量和難度都非常大。

4)JDK NIO 的 Bug:例如臭名昭著的 Epoll Bug,它會導致 Selector 空輪詢,最終導致 CPU 100%。官方聲稱在 JDK 1.6 版本的 update 18 修復了該問題,但是直到 JDK 1.7 版本該問題仍舊存在,只不過該 Bug 發生概率降低了一些而已,它並沒有被根本解決。

03

Netty框架的優勢

  • API使用簡單,開發門檻低;
  • 功能強大,預置了多種編解碼功能,支持多種主流協議;
  • 定製能力強,可以通過ChannelHandler對通信框架進行靈活地擴展;
  • 性能高,通過與其他業界主流的NIO框架對比,Netty的綜合性能最優;
  • 成熟、穩定,Netty修復了已經發現的所有JDK NIO BUG,業務開發人員不需要再為NIO的BUG而煩惱;
  • 社區活躍,版本迭代週期短,發現的BUG可以被及時修復,同時,更多的新功能會加入;
  • 經歷了大規模的商業應用考驗,質量得到驗證。在互聯網、大數據、網絡遊戲、企業應用、電信軟件等眾多行業得到成功商用,證明了它已經完全能夠滿足不同行業的商業應用了。

04

Netty的架構設計

總體結構

Netty 採用了比較典型的三層網絡架構進行設計,邏輯架構圖如下所示:

高併發架構系列:Netty的實現原理、特點與優勢、適用場景

1)傳輸服務:支持 BIO 和 NIO;

2)容器集成:支持 OSGI、JBossMC、Spring、Guice 容器;

3)協議支持:HTTP、Protobuf、二進制、文本、WebSocket 等一系列常見協議都支持。還支持通過實行編碼解碼邏輯來實現自定義協議;

4)Core 核心:可擴展事件模型、通用通信 API、支持零拷貝的 ByteBuf 緩衝對象。


05

Netty的高性能設計

1.高性能的三大要素

高併發架構系列:Netty的實現原理、特點與優勢、適用場景

1) 傳輸:用什麼樣的通道將數據發送給對方,BIO、NIO或者AIO,IO模型在很大程度上決定了框架的性能。

2) 協議:採用什麼樣的通信協議,HTTP或者內部私有協議。協議的選擇不同,性能模型也不同。相比於公有協議,內部私有協議的性能通常可以被設計的更優。

3) 線程:數據報如何讀取?讀取之後的編解碼在哪個線程進行,編解碼後的消息如何派發,Reactor線程模型的不同,對性能的影響也非常大。

2.IO模型

Netty的I/O模型基於非阻塞I/O實現,底層依賴的是JDK NIO框架的Selector。

3.Reactor線程模型

關於Java NIO 構造Reator模式,Doug lea在《Scalable IO in Java》中給了很好的闡述,這裡截取PPT對Reator模式的實現進行說明。

1)Reactor單線程模型:Reactor單線程模型,指的是所有的I/O操作都在同一個NIO線程上面完成。對於一些小容量應用場景,可以使用單線程模型。

高併發架構系列:Netty的實現原理、特點與優勢、適用場景

2)Reactor多線程模型:Rector多線程模型與單線程模型最大的區別就是有一組NIO線程處理I/O操作。主要用於高併發、大業務量場景。

高併發架構系列:Netty的實現原理、特點與優勢、適用場景

3)主從Reactor多線程模型:主從Reactor線程模型的特點是服務端用於接收客戶端連接的不再是個1個單獨的NIO線程,而是一個獨立的NIO線程池。利用主從NIO線程模型,可以解決1個服務端監聽線程無法有效處理所有客戶端連接的性能不足問題。

高併發架構系列:Netty的實現原理、特點與優勢、適用場景

4.Netty的線程模型

說完了Reactor的三種模型,那麼Netty是哪一種呢?其實Netty的線程模型是Reactor模型的變種,那就是去掉線程池的第三種形式的變種,這也是Netty NIO的默認模式。

06

Netty的核心組件

Netty應用中必不可少的組件:

  • Bootstrap or ServerBootstrap
  • EventLoop
  • EventLoopGroup
  • ChannelPipeline
  • Channel
  • Future or ChannelFuture
  • ChannelInitializer
  • ChannelHandler

1.Bootstrap

一個Netty應用通常由一個Bootstrap開始,它主要作用是配置整個Netty程序,串聯起各個組件。

Handler,為了支持各種協議和處理數據的方式,便誕生了Handler組件。Handler主要用來處理各種事件,這裡的事件很廣泛,比如可以是連接、數據接收、異常、數據轉換等。

2.ChannelInboundHandler

一個最常用的Handler。這個Handler的作用就是處理接收到數據時的事件,也就是說,我們的業務邏輯一般就是寫在這個Handler裡面的,ChannelInboundHandler就是用來處理我們的核心業務邏輯。

3.ChannelInitializer

當一個鏈接建立時,我們需要知道怎麼來接收或者發送數據,當然,我們有各種各樣的Handler實現來處理它,那麼ChannelInitializer便是用來配置這些Handler,它會提供一個ChannelPipeline,並把Handler加入到ChannelPipeline。

4.ChannelPipeline

一個Netty應用基於ChannelPipeline機制,這種機制需要依賴於EventLoop和EventLoopGroup,因為它們三個都和事件或者事件處理相關。

EventLoops的目的是為Channel處理IO操作,一個EventLoop可以為多個Channel服務。EventLoopGroup會包含多個EventLoop。

5.Channel

代表了一個Socket鏈接,或者其它和IO操作相關的組件,它和EventLoop一起用來參與IO處理。

6.Future

在Netty中所有的IO操作都是異步的,因此,你不能立刻得知消息是否被正確處理,但是我們可以過一會等它執行完成或者直接註冊一個監聽,具體的實現就是通過Future和ChannelFutures,他們可以註冊一個監聽,當操作執行成功或失敗時監聽會自動觸發。

總之,所有的操作都會返回一個ChannelFuture。

07

Netty的應用場景

1.互聯網行業

在分佈式系統中,各個節點之間需要遠程服務調用,高性能的RPC框架必不可少,Netty作為異步高新能的通信框架,往往作為基礎通信組件被這些RPC框架使用。

典型的應用有:阿里分佈式服務框架Dubbo的RPC框架使用Dubbo協議進行節點間通信,Dubbo協議默認使用Netty作為基礎通信組件,用於實現各進程節點之間的內部通信。

除了 Dubbo 之外,淘寶的消息中間件 RocketMQ 的消息生產者和消息消費者之間,也採用 Netty 進行高性能、異步通信。

2.遊戲行業

無論是手遊服務端還是大型的網絡遊戲,Java語言得到了越來越廣泛的應用。Netty作為高性能的基礎通信組件,它本身提供了TCP/UDP和HTTP協議棧。

非常方便定製和開發私有協議棧,賬號登錄服務器,地圖服務器之間可以方便的通過Netty進行高性能的通信。

3.大數據領域

經典的Hadoop的高性能通信和序列化組件Avro的RPC框架,默認採用Netty進行跨界點通信,它的Netty Service基於Netty框架二次封裝實現。

-end-

相關推薦

推薦中...