天天看點

Netty面試題系列(1)

1.Netty 是什麼?

Netty 是一款基于 NIO(Nonblocking I/O,非阻塞IO)開發的網絡通信架構,對比于 BIO(Blocking I/O,阻塞IO),他的并發性能得到了很大提高。難能可貴的是,在保證快速和易用性的同時,并沒有喪失可維護性和性能等優勢。

2.Netty 的特點是什麼?

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

傳輸快:Netty 的傳輸依賴于零拷貝特性,盡量減少不必要的記憶體拷貝,實作了更高效率的傳輸。

封裝好:Netty 封裝了 NIO 操作的很多細節,提供了易于使用調用接口。

3.什麼是 Netty 的零拷貝?

Netty 的零拷貝主要包含三個方面:

Netty 的接收和發送 ByteBuffer 采用 DIRECT BUFFERS,使用堆外直接記憶體進行 Socket 讀寫,不需要進行位元組緩沖區的二次拷貝。如果使用傳統的堆記憶體(HEAP BUFFERS)進行 Socket 讀寫,JVM 會将堆記憶體 Buffer 拷貝一份到直接記憶體中,然後才寫入 Socket 中。相比于堆外直接記憶體,消息在發送過程中多了一次緩沖區的記憶體拷貝。

Netty 提供了組合 Buffer 對象,可以聚合多個 ByteBuffer 對象,使用者可以像操作一個 Buffer 那樣友善的對組合 Buffer 進行操作,避免了傳統通過記憶體拷貝的方式将幾個小 Buffer 合并成一個大的 Buffer。

Netty 的檔案傳輸采用了 transferTo 方法,它可以直接将檔案緩沖區的資料發送到目标 Channel,避免了傳統通過循環 write 方式導緻的記憶體拷貝問題。

4.Netty 的優勢有哪些?

使用簡單:封裝了 NIO 的很多細節,使用更簡單。

功能強大:預置了多種編解碼功能,支援多種主流協定。

定制能力強:可以通過 ChannelHandler 對通信架構進行靈活地擴充。

性能高:通過與其他業界主流的 NIO 架構對比,Netty 的綜合性能最優。

穩定:Netty 修複了已經發現的所有 NIO 的 bug,讓開發人員可以專注于業務本身。

社群活躍:Netty 是活躍的開源項目,版本疊代周期短,bug 修複速度快。

5.Netty 的應用場景有哪些?

典型的應用有:阿裡分布式服務架構 Dubbo,預設使用 Netty 作為基礎通信元件,還有 RocketMQ 也是使用 Netty 作為通訊的基礎。

6.Netty 高性能表現在哪些方面?

IO 線程模型:同步非阻塞,用最少的資源做更多的事。

記憶體零拷貝:盡量減少不必要的記憶體拷貝,實作了更高效率的傳輸。

記憶體池設計:申請的記憶體可以重用,主要指直接記憶體。内部實作是用一顆二叉查找樹管理記憶體配置設定情況。

串形化處理讀寫:避免使用鎖帶來的性能開銷。

高性能序列化協定:支援 protobuf 等高性能序列化協定。

7.Netty 和 Tomcat 的差別?

作用不同:Tomcat 是 Servlet 容器,可以視為 Web 伺服器,而 Netty 是異步事件驅動的網絡應用程式架構和工具用于簡化網絡程式設計,例如TCP和UDP套接字伺服器。

協定不同:Tomcat 是基于 http 協定的 Web 伺服器,而 Netty 能通過程式設計自定義各種協定,因為 Netty 本身自己能編碼/解碼位元組流,所有 Netty 可以實作,HTTP 伺服器、FTP 伺服器、UDP 伺服器、RPC 伺服器、WebSocket 伺服器、Redis 的 Proxy 伺服器、MySQL 的 Proxy 伺服器等等。

8.Netty 中有那種重要元件?

Channel:Netty 網絡操作抽象類,它除了包括基本的 I/O 操作,如 bind、connect、read、write 等。

EventLoop:主要是配合 Channel 處理 I/O 操作,用來處理連接配接的生命周期中所發生的事情。

ChannelFuture:Netty 架構中所有的 I/O 操作都為異步的,是以我們需要 ChannelFuture 的 addListener()注冊一個 ChannelFutureListener 監聽事件,當操作執行成功或者失敗時,監聽就會自動觸發傳回結果。

ChannelHandler:充當了所有處理入站和出站資料的邏輯容器。ChannelHandler 主要用來處理各種事件,這裡的事件很廣泛,比如可以是連接配接、資料接收、異常、資料轉換等。

ChannelPipeline:為 ChannelHandler 鍊提供了容器,當 channel 建立時,就會被自動配置設定到它專屬的 ChannelPipeline,這個關聯是永久性的。

9.Netty 發送消息有幾種方式?

Netty 有兩種發送消息的方式:

直接寫入 Channel 中,消息從 ChannelPipeline 當中尾部開始移動;

寫入和 ChannelHandler 綁定的 ChannelHandlerContext 中,消息從 ChannelPipeline 中的下一個 ChannelHandler 中移動。

10.預設情況 Netty 起多少線程?何時啟動?

Netty 預設是 CPU 處理器數的兩倍,bind 完之後啟動。

11.Netty 支援哪些心跳類型設定?

readerIdleTime:為讀逾時時間(即測試端一定時間内未接受到被測試端消息)。

writerIdleTime:為寫逾時時間(即測試端一定時間内向被測試端發送消息)。

allIdleTime:所有類型的逾時時間。