Netty是一個高性能、非同步事件驅動的NIO框架,它提供了對TCP、UDP和文件傳輸的支持。作為當前最流行的NIO框架,Netty在互聯網領域、大數據分散式計算領域、遊戲行業、通信行業等獲得了廣泛的應用,一些業界著名的開源組件也基於Netty的NIO框架構建。
Netty 利用 Java 高級網路的能力,隱藏其背後的複雜性而提供一個易於使用的 API 構建一個客戶端/服務端,其具有高並發、傳輸快、封裝好等特點。
高並發
Netty是一款基於NIO(Nonblocking I/O,非阻塞IO)開發的網路通信框架,對比於BIO(Blocking I/O,阻塞IO),他的並發性能得到了很大提高 。
傳輸快
Netty的傳輸快其實也是依賴了NIO的一個特性——零拷貝。
封裝好
Netty封裝了NIO操作的很多細節,提供易於使用的API,還有心跳、重連機制、拆包粘包方案等特性,使開發者能能夠快速高效的構建一個穩健的高並發應用。
Netty項目致力於提供一個非同步的、事件驅動的網路應用框架和工具,用於快速開發可維護的、高性能的、高擴展性的伺服器和客戶端之間的協議。換句話說,Netty式一個NIO客戶端伺服器框架,能夠快速、輕鬆地開發網路應用例如伺服器和客戶端間的協議。它簡化了網路編程如TCP/IP socket伺服器。
JBOSSes Netty的設計吸取了大量的協議如FTP、SMTP、HTTP和各種二進位、基於文本的繼承協議等協議的設計經驗,成功地找到了一種方法實現易於開發、性能、穩定、靈活的協議開發。
特徵:
Netty為用戶提供了很多創新和更好的網路開發體驗。
1)設計Design
為各種傳輸類型(塊和非塊socket)提供了統一的API;
建立在靈活和可擴展的事件模型;
高度可定製的線程模式——單線程,一個或多個線程池(如SEDA);
可信的五連接數據報socket支持。
2)易於使用
良好文檔化的Javadoc、用戶嚮導和例子;
結構並不臃腫;
無其它的依賴,只需JDK1.5或以上。
3)性能
高吞吐量、低延遲時間;
很小的資源消耗;
最小化不必要的內存複製。
4)健壯性
不會因為快速連接、慢速連接或超載連接引起OutOfMemoryError錯誤;
高速網路下不會引起NIO程序的讀寫異常。
5)安全
完全支持SSL/TLS和StartTLS;
在Java Applet環境下運行正常。
6)社區
至少每兩週一個版本發布。
項目主頁: http://www.jboss.org/netty/
文檔地址: http://www.jboss.org/netty/documentation.html
下載地址: http://www.jboss.org/netty/downloads.html
Socket通信(IO/NIO/AIO)編程,對於通信模型已經有了一個基本的認識。我們學習的僅僅是一個模型,如果想把這些真正的用於實際工作中,那麼還需要不斷的完善、擴展和優化。比如經典的TCP讀包寫包問題,或者是數據接收的大小,實際的通信處理與應答的處理邏輯等等一些細節問題需要認真的去思考,而這些都需要大量的時間和經歷,以及豐富的經驗。所以想學好Socket通信不是件容易事,那麼接下來就來學習一下新的技術Netty,為什麼會選擇Netty?因為它簡單!使用Netty不必編寫複雜的邏輯代碼去實現通信,再也不需要去考慮性能問題,不需要考慮編碼問題,半包讀寫等問題。強大的Netty已經幫我們實現好了,我們只需要使用即可。
Netty是最流行的NIO框架,它的健壯性、功能、性能、可定製性和可擴展性在同類框架都是首屈一指的。它已經得到成百上千的商業/商用項目驗證,如Hadoop的RPC框架Avro、RocketMQ以及主流的分散式通信框架Dubbox等等。
並發系統可以採用多種並發編程模型來實現。並發模型指定了系統中的線程如何通過協作來完成分配給它們的作業。不同的並發模型採用不同的方式拆分作業,同時線程間的協作和交互方式也不相同。
對於網路請求一般可以分為兩個處理階段,一是接收請求任務,二是處理網路請求。根據不同階段處理方式分為以下幾種線程模型:
串列化處理模型
這個模型中用一個線程來處理網路請求連接和任務處理,當worker接受到一個任務之後,就立刻進行處理,也就是說任務接受和任務處理是在同一個worker線程中進行的,沒有進行區分。這樣做存在一個很大的問題是,必須要等待某個task處理完成之後,才能接受處理下一個task。
而通常情況下,任務的處理過程會比任務的接受流程慢得多。例如在處理任務的時候,我們可能會需要訪問遠程資料庫,這屬於一種網路IO。通常情況下IO操作是比較耗時的,這直接影響了下一個任務的接受,而且通常在IO操作的時候,CPU是比較空閑的,白白浪費了資源。
因此可以把接收任務和處理任務兩個階段分開處理,一個線程接收任務,放入任務隊列,另外的線程非同步處理任務隊列中的任務。
並行化處理模型
由於任務處理一般比較緩慢,會導致任務隊列中任務積壓長時間得不到處理,這時可以使用多線程來處理。這裡使用的是一個公共的任務隊列,多線程環境中不免要通過加鎖來保證線程安全,我們常用的線程池就是這種模式。可以通過為每個線程維護一個任務隊列來改進這種模型。
Reactor線程模型
reactor線程模型關注的是:任務接受之後,對處理過程繼續進行切分,劃分為多個不同的步驟,每個步驟用不同的線程來處理,也就是原本由一個線程處理的任務現在由多個線程來處理,每個線程在處理完自己的步驟之後,還需要將任務轉發到下階段線程繼續進行處理。
其中mainReacotor,subReactor,Thread Pool是三個線程池。mainReactor負責處理客戶端的連接請求,並將accept的連接註冊到subReactor的其中一個線程上;subReactor負責處理客戶端通道上的數據讀寫;Thread Pool是具體的業務邏輯線程池,處理具體業務。
Netty具體線程模型
如何理解NioEventLoop和NioEventLoopGroup
1)NioEventLoop實際上就是工作線程,可以直接理解為一個線程。NioEventLoopGroup是一個線程池,線程池中的線程就是NioEventLoop。
2)實際上bossGroup中有多個NioEventLoop線程,每個NioEventLoop綁定一個埠,也就是說,如果程序只需要監聽1個埠的話,bossGroup裡面只需要有一個NioEventLoop線程就行了。
每個NioEventLoop都綁定了一個Selector,所以在Netty的線程模型中,是由多個Selecotr在監聽IO就緒事件。而Channel註冊到Selector。
一個Channel綁定一個NioEventLoop,相當於一個連接綁定一個線程,這個連接所有的ChannelHandler都是在一個線程中執行的,避免了多線程幹擾。更重要的是ChannelPipline鏈表必須嚴格按照順序執行的。單線程的設計能夠保證ChannelHandler的順序執行。
一個NioEventLoop的selector可以被多個Channel註冊,也就是說多個Channel共享一個EventLoop。EventLoop的Selecctor對這些Channel進行檢查。
在監聽一個埠的情況下,一個NioEventLoop通過一個NioServerSocketChannel監聽埠,處理TCP連接。後端多個工作線程NioEventLoop處理IO事件。每個Channel綁定一個NioEventLoop線程,1個NioEventLoop線程關聯一個selector來為多個註冊到它的Channel監聽IO就緒事件。NioEventLoop是單線程執行,保證Channel的pipline在單線程中執行,保證了ChannelHandler的執行順序。
小編準備了關於netty的面試題分享給大家,由於文章篇幅原因以下只分享10道netty的面試題。後五道題未設置答案,需要獲取答案和更多Java架構資料、面試題(含答案)和麪試心得以及視頻資料的可以私信【資料】獲取!同時歡迎大家關注我,需要更多Java面試資料和學習乾貨可以關注我的專欄【Tom貓的Java屋本專欄會長期更新java架構技術以及心得等精彩文章!
1.BIO、NIO和AIO的區別?
2.NIO的組成?
3.Netty的特點?
4.Netty的線程模型?
5.TCP 粘包/拆包的原因及解決方法?
6.瞭解哪幾種序列化協議?
7.如何選擇序列化協議?
8.Netty的零拷貝實現?
9.Netty的高性能表現在哪些方面?
10.NIOEventLoopGroup源碼?
如果你想突破自己的天花板,那一定要比別人付出更多,這個過程是很辛苦的。如果你認準了一條路,堅持走下去,你一定會獲得很多收穫和你滿意的答案。
最後,希望以上的分享能給大家帶來收穫。更多面試題領取方式私信【資料】免費獲取
推薦閱讀: