netty 概念篇

netty是什麼?java

  Netty是由JBOSS提供的一個java開源框架。Netty提供異步的、事件驅動的網絡應用程序框架和工具,用以快速開發高性能、高可靠性的網絡服務器和客戶端程序。web

  也就是說,Netty 是一個基於NIO的客戶、服務器端編程框架,使用Netty 能夠確保你快速和簡單的開發出一個網絡應用,例如實現了某種協議的客戶、服務端應用。Netty至關於簡化和流線化了網絡應用的編程開發過程,例如:基於TCP和UDP的socket服務開發。redis

  「快速」和「簡單」並不用產生維護性或性能上的問題。Netty 是一個吸取了多種協議(包括FTP、SMTP、HTTP等各類二進制文本協議)的實現經驗,並通過至關精心設計的項目。最終,Netty 成功的找到了一種方式,在保證易於開發的同時還保證了其應用的性能,穩定性和伸縮性。數據庫

Netty和Tomcat有什麼區別?

 

  Netty和Tomcat最大的區別就在於通訊協議,Tomcat是基於Http協議的,他的實質是一個基於http協議的web容器,可是Netty不同,他能經過編程自定義各類協議,由於netty可以經過codec本身來編碼/解碼字節流,完成相似redis訪問的功能,這就是netty和tomcat最大的不一樣。apache

  有人說netty的性能就必定比tomcat性能高,其實否則,tomcat從6.x開始就支持了nio模式,而且後續還有arp模式——一種經過jni調用apache網絡庫的模式,相比於舊的bio模式,併發性能獲得了很大提升,特別是arp模式,而netty是否比tomcat性能更高,則要取決於netty程序做者的技術實力了。編程

爲何Netty受歡迎?

如第一部分所述,netty是一款收到大公司青睞的框架,在我看來,netty可以受到青睞的緣由有三:  tomcat

  1. 併發高
  2. 傳輸快
  3. 封裝好

Netty爲何併發高?

  Netty是一款基於NIO(Nonblocking I/O,非阻塞IO)開發的網絡通訊框架,對比於BIO(Blocking I/O,阻塞IO),他的併發性能獲得了很大提升,兩張圖讓你瞭解BIO和NIO的區別:服務器

                            阻塞方式的io網絡

 

               非阻塞方式的io併發

從這兩圖能夠看出,NIO的單線程能處理鏈接的數量比BIO要高出不少,而爲何單線程能處理更多的鏈接呢?緣由就是圖二中出現的Selector

當一個鏈接創建以後,他有兩個步驟要作,第一步是接收完客戶端發過來的所有數據,第二步是服務端處理完請求業務以後返回response給客戶端。NIO和BIO的區別主要是在第一步。

在BIO中,等待客戶端發數據這個過程是阻塞的,這樣就形成了一個線程只能處理一個請求的狀況,而機器能支持的最大線程數是有限的,這就是爲何BIO不能支持高併發的緣由。

而NIO中,當一個Socket創建好以後,Thread並不會阻塞去接受這個Socket,而是將這個請求交給Selector,Selector會不斷的去遍歷全部的Socket,一旦有一個Socket創建完成,他會通知Thread,而後Thread處理完數據再返回給客戶端——這個過程是阻塞的,這樣就能讓一個Thread處理更多的請求了。
下面兩張圖是基於BIO的處理流程和netty的處理流程,輔助你理解兩種方式的差異:
                                BIO
                         
                                             NIO
                                                     
      五種常見的IO模型
  • BIO,同步阻塞IO,阻塞整個步驟,若是鏈接少,他的延遲是最低的,由於一個線程只處理一個鏈接,適用於少鏈接且延遲低的場景,好比說數據庫鏈接。
  • NIO,同步非阻塞IO,阻塞業務處理但不阻塞數據接收,適用於高併發且處理簡單的場景,好比聊天軟件。
  • 多路複用IO,他的兩個步驟處理是分開的,也就是說,一個鏈接可能他的數據接收是線程a完成的,數據處理是線程b完成的,他比BIO能處理更多請求,可是比不上NIO,可是他的處理性能又比BIO更差,由於一個鏈接他須要兩次system call,而BIO只須要一次,因此這種IO模型應用的很少。
  • 信號驅動IO,這種IO模型主要用在嵌入式開發,不參與討論。
  • 異步IO,他的數據請求和數據處理都是異步的,數據請求一次返回一次,適用於長鏈接的業務場景。
       

  Netty爲何傳輸快?

    Netty的傳輸快其實也是依賴了NIO的一個特性——零拷貝。咱們知道,Java的內存有堆內存、棧內存和字符串常量池等等,其中堆內存是佔用內存空間最大的一塊,也是Java對象存放的地方,通常咱們的數據若是須要從IO讀取到堆內存,中間須要通過Socket緩衝區,也就是說一個數據會被拷貝兩次才能到達他的的終點,若是數據量大,就會形成沒必要要的資源浪費。
Netty針對這種狀況,使用了NIO中的另外一大特性——零拷貝,當他須要接收數據的時候,他會在堆內存以外開闢一塊內存,數據就直接從IO讀到了那塊內存中去,在netty裏面經過ByteBuf能夠直接對這些數據進行直接操做,從而加快了傳輸速度。
     下兩圖就介紹了兩種拷貝方式的區別
   1.傳統拷貝

   
   2.零拷貝
   
          
   上文介紹的ByteBuf是Netty的一個重要概念,他是netty數據處理的容器,也是Netty封裝好的一個重要體現
    

    爲何說Netty封裝好?

  

  • Channel,表示一個鏈接,能夠理解爲每個請求,就是一個Channel。
  • ChannelHandler,核心處理業務就在這裏,用於處理業務請求。
  • ChannelHandlerContext,用於傳輸業務數據。
  • ChannelPipeline,用於保存處理過程須要用到的ChannelHandler和ChannelHandlerContext。
           

       Codec
    Netty中的編碼/解碼器,經過他你能完成字節與pojo、pojo與pojo的相互轉換,從而達到自定義協議的目的。
    在Netty裏面最有名的就是HttpRequestDecoder和HttpResponseEncoder了。

相關文章
相關標籤/搜索