前言
Netty框架部分的題目,是我根據Java Guide的面試突擊版本V3.0再整理出來的,其中,我選擇了一些比較重要的問題,並重新做出相應回答,並添加了一些比較重要的問題,希望對大家起到一定的幫助。
系列文章:
Netty框架
-
Netty 是什么?
- Netty是一個基於NIO的client-server框架,使用它可以快速開發網絡應用程序
- 並且支持多種協議,包括FTP,HTTP以及各種二進制和基於文本的傳輸協議
-
為什么要⽤ Netty?
- 阻塞和⾮阻塞的Socket都使用統一的API,便於開發
- 實現了強大的線程模型
- 自帶解決粘包拆包的解碼器
- 社區活躍,經歷了大型項目的考驗,成熟穩定
-
Netty 應⽤場景了解么?
- 我們項目中的就是利用Netty實現了一個自有協議的網絡服務器
- 很多分布式框架的網絡通信工具,比如我們項目中使用的Storm底層也是使用Netty進行通信的
-
Netty 核⼼組件有哪些?分別有什么作⽤?
- Channel:Netty對網絡操作的抽象,包括了一些常見的網絡IO操作,比如read,write等等,最常見的實現類:NioServerSocketChannel和NioSocketChannel,對應Bio中的ServerSocketChannel和SocketChannel
- EventLoop:負責監聽網絡事件並調用事件處理器進行相關的處理
- ChannelFuture:Netty是異步的,所有操作都可以通過ChannelFuture來實現綁定一個監聽器然后執行結果成功與否的業務邏輯,或者把通過調用sync方法,把異步方法變成同步的。
- ChannelHandler 和 ChannelPipeline:Netty底層的處理器是一個處理器鏈,鏈條上的每一個處理器都可以對消息進行處理,選擇繼續傳遞或者到此為止,一般我們業務會實現自己的解碼器/心跳處理器和實際的業務處理Handler,然后按照順序綁定到鏈條上。
-
EventloopGroup 了解么?和 EventLoop 啥關系?
EventLoop可以理解為線程,那么Group就是線程池或者線程組,Netty的線程模型中,每一個channel需要綁定到一個固定的EventLoop進行后續的處理,Netty就是根據某一個算法從線程組中選擇一個線程進行綁定的。
-
Bootstrap 和 ServerBootstrap 了解么?
BootStarp和ServerBootstrap都是一個啟動引導類,相當於如果要使用Netty需要把相關信息配置到啟動引導類中,這樣Netty才能正確工作。
-
Bootstrap是客戶端引導類,核心方法是connect,傳入一個EventLoopGroup就可以
-
ServerBootstrap是服務斷引導類,核心方法是bind,需要傳入兩個EventLoopGroup,一個負責接受連接,一個負責處理具體的連接上的網絡IO任務。
-
-
NioEventLoopGroup 默認的構造函數會起多少線程?
NioEventLoopGroup 默認的構造函數實際會起的線程數為 CPU核⼼數*2 。
-
Netty 線程模型了解么?
Netty主要靠配置EventLoopGroup來實現具體的線程模型的。
以服務端開發為例,通過配置不同的線程數量可以實現不同的線程模型。
- 單線程:兩個EventloopGroup都是用同一個只為1的group,這意味着一個線程需要處理所有的socket的所有網絡IO事件,對高負載高並發高性能的場景不適用。
- 多線程:一個acceptor線程負責監聽連接,N個EventLoop負責處理具體連接的網絡IO,但是如果並發連接大,就會出現性能問題
- 主從模型:主從模型就是acceptor連接線程使用線程池來實現,我們具體項目也是使用這種方式的。
-
什么是 TCP 粘包/拆包?
TCP的粘包拆包指的是,基於TCP發送數據時,多條消息會在一個包中粘在一起,或者一條消息直接被分為兩個包發送過來,我們需要正確的處理,把每條消息都正確的拆分和合並起來。
-
簡單說說Netty中自帶的解決粘包拆包的解碼器類型吧?
Netty自帶四種解決粘包拆包的解碼器。
- LineBasedFrameDecoder :基於換行符的解碼器
- DelimiterBasedFrameDecoder:基於分隔符的解碼器
- FixedLengthFrameDecoder:基於固定長度的解碼器
- LengthFieldBasedFrameDecoder:基於消息中的消息長度字段進行解碼的解碼器,我們項目中實際使用的就是這種解碼器,核心就是傳入長度字節的起始位置和長度即可。
-
⻓連接是什么
-
什么是連接:TCP協議中如果兩端想要傳遞數據,首先需要通過三次握手建立連接,握手完畢,連接就建立完畢,但是這個過程是比較消耗網絡資源的。
-
短連接:一輪數據傳輸完畢后,就斷開連接,實現和管理都很方便,但是頻繁的建立斷開連接比較消耗網絡資源。
-
長連接:數據傳輸完畢后,不斷開連接,下次有數據發送需求的時候再使用這個連接,省去了握手的過程。
-
-
如何實現長連接?
我在自己的博客中專門寫過一篇博客總結過為什么需要保活機制,詳見此 網絡編程-為什么需要應用層做心跳處理?總結來說,依賴TCP的超時或者Keep alive機制,在最差情況下的超時時間都是不可接受的,所以我們需要通過定時發送帶序號的心跳包來實現應用層保活,並且為了防止誤判,需要多發送幾次心跳包來檢測,在我們具體的業務實現中,使用的是Netty的IdeStateHandle中的回調方法來實現心跳機制。
-
Netty 的零拷⻉了解么?
首先說說什么是零拷貝:
- 零拷貝技術指的是,cpu不需要為了在內存中拷貝數據而消耗資源
- Netty中的零拷貝技術表現形式有下面幾種:
- 可以把文件中的數據直接發送到發送緩沖區中,底層用的是操作系統提供的sendFile系統調用(節省了內核到用戶空間和用戶空間到內核的兩次拷貝)。 參考材料: 內核零拷貝的實現原理
- 允許多段數據合並為一段虛擬數據供用戶使用,節約了copy的消耗