1. 程式人生 > >Netty介紹(一)————為什麼使用Netty

Netty介紹(一)————為什麼使用Netty

Netty的簡單介紹

Netty 是一個 NIO client-server(客戶端伺服器)框架,使用 Netty 可以快速開發網路應用,例如伺服器和客戶 端協議。 Netty 提供了一種新的方式來使開發網路應用程式,這種新的方式使得它很容易使用和有很強的擴充套件性。 Netty 的內部實現時很複雜的,但是 Netty 提供了簡單易用的 api 從網路處理程式碼中解耦業務邏輯。 Netty 是完全基 於 NIO 實現的,所以整個 Netty 都是非同步的。
簡單點說就是Netty提供了一個簡單,間接的方法來操作網路之間的通訊。

不選擇JAVA原生NIO和IO的原因

基於IO的經典同步堵塞模型:

經典的IO模型也就是傳統的伺服器端同步阻塞I/O處理(也就是BIO,Blocking I/O)的經典程式設計模型,當我們每得到一個新的連線時,就會開啟一個執行緒來處理這個連線的任務。之所以使用多執行緒,主要原因在於socket.accept()、socket.read()、socket.write()三個主要函式都是同步阻塞的,當一個連線在處理I/O的時候,系統是阻塞的,如果是單執行緒的話必然就掛死在那裡;但CPU是被釋放出來的,開啟多執行緒,就可以讓CPU去處理更多的事情。

因此這個模型最本質的問題在於,嚴重依賴於執行緒。但執行緒是很”貴”的資源,主要表現在:

  1. 執行緒的建立和銷燬成本很高,在Linux這樣的作業系統中,執行緒本質上就是一個程序。建立和銷燬都是重量級的系統函式。
    執行緒本身佔用較大記憶體,像Java的執行緒棧,一般至少分配512K~1M的空間,如果系統中的執行緒數過千,恐怕整個JVM的記憶體都會被吃掉一半。

  2. 執行緒的切換成本是很高的。作業系統發生執行緒切換的時候,需要保留執行緒的上下文,然後執行系統呼叫。如果執行緒數過高,可能執行執行緒切換的時間甚至會大於執行緒執行的時間,這時候帶來的表現往往是系統load偏高、CPU sy使用率特別高(超過20%以上),導致系統幾乎陷入不可用的狀態。

  3. 容易造成鋸齒狀的系統負載。因為系統負載是用活動執行緒數或CPU核心數,一旦執行緒數量高但外部網路環境不是很穩定,就很容易造成大量請求的結果同時返回,啟用大量阻塞執行緒從而使系統負載壓力過大。

基於NIO的非同步模型:

NIO是一種同步非阻塞的I/O模型,也是I/O多路複用的基礎,而且已經被越來越多地應用到大型應用伺服器,成為解決高併發與大量連線、I/O處理問題的有效方式。

[Java NIO介紹(二)————無堵塞io和Selector簡單介紹]

不使用NIO的原因:

  1. NIO的類庫和API繁雜。需要很多額外的技能做鋪墊。例如需要很熟悉Java多執行緒程式設計、Selector執行緒模型。導致工作量和開發難度都非常大。
  2. 擴充套件 ByteBuffer:NIO和Netty都有ByteBuffer來操作資料,但是NIO的ByteBuffer長度固定而且操作複雜,許多操作甚至都需要自己實現。而且它的建構函式是私有,不能擴充套件。Netty 提供了自己的
    ByteBuffer 實現, Netty 通過一些簡單的 APIs 對 ByteBuffer 進行構造、使用和操作,以此來解決 NIO 中的一些限制。
  3. NIO 對緩衝區的聚合和分散操作可能會操作記憶體洩露,到jdk7才解決了記憶體洩露的問題

為什麼選擇Netty

  • API使用簡單,開發門檻低。
  • 功能強大,預置了多種編解碼功能,支援多種協議開發。
  • 定製能力強,可以通過ChannelHadler進行擴充套件。
  • 效能高,對比其它NIO框架,Netty綜合性能最優。
  • 經歷了大規模的應用驗證。在網際網路、大資料、網路遊戲、企業應用、電信軟體得到成功,很多著名的框架通訊底層就用了Netty,比如Dubbo
  • 穩定,修復了NIO出現的所有Bug。
  • 切換IO和NIO,因為IO和NIO的API完全不同,相互切換非常困難。

類似的框架對比:

與Mina相比有什麼優勢?

1、都是Trustin Lee的作品,Netty更晚;

2、Mina將核心和一些特性的聯絡過於緊密,使得使用者在不需要這些特性的時候無法脫離,相比下效能會有所下降,Netty解決了這個設計問題;

3、Netty的文件更清晰,很多Mina的特性在Netty裡都有;

4、Netty更新週期更短,新版本的釋出比較快;

5、它們的架構差別不大,Mina靠apache生存,而Netty靠jboss,和jboss的結合度非常高,Netty有對google protocal buf的支援,有更完整的ioc容器支援(spring,guice,jbossmc和osgi);

6、Netty比Mina使用起來更簡單,Netty裡你可以自定義的處理upstream events 或/和 downstream events,可以使用decoder和encoder來解碼和編碼傳送內容;

7、Netty和Mina在處理UDP時有一些不同,Netty將UDP無連線的特性暴露出來;而Mina對UDP進行了高階層次的抽象,可以把UDP當成”面向連線”的協議,而要Netty做到這一點比較困難。