1. 程式人生 > >Netty4詳解一:理解Netty的設計理念NIO

Netty4詳解一:理解Netty的設計理念NIO

  • 有一套統一的API來處理非同步和同步程式設計模式
  • 使用非常靈活
  • 簡單但卻強大的執行緒機制
  • 業務元件分離方便重用
  • 極小的縮減不必要的Memory Copy
     Netty開始-理解Netty的設計理念NIONetty開始-理解Netty的設計理念NIO
二、非同步程式設計模式設計      一般來說網路程式設計都會面臨著併發問題,那麼我們就來看一下為何非同步程式設計模式會很好的解決這個問題,其實這也就詮釋了netty背後的設計思想。      在現在,瓶頸總是在IO處理上,非同步的處理方式就是你可以不用一直等待任務(IO)處理完成,而是在任務進行的時候還可以做其它事情。那麼如何實現這個呢?讓我們來認識一下實現非同步的兩種處理方式:      CallBack:
回撥是非同步處理經常用到的程式設計模式,回撥函式通常被繫結到一個方法上,並且在方法完成之後才執行,這種處理方式在javascript當中得到了充分的運用。回撥給我們帶來的難題是當一個問題處理過程中涉及很多回調時,程式碼是很難讀的。      Futures:Futures是一種抽象,它代表一個事情的執行過程中的一些關鍵點,我們通過Future就可以知道任務的執行情況,比如當任務沒完成時我們可以做一些其它事情。它給我們帶來的難題是我們需要去判斷future的值來確定任務的執行狀態。      其實這兩者很難界定那個好或壞,其實Netty中這兩者都有用到。 非同步模式(NIO)和非非同步模式(BIO)(
N可以理解為non-blocking或new      Block IO會對每個連線建立一個執行緒,因此這極大限制了JVM建立執行緒的數量(當然執行緒池可緩解這個問題,但是也僅僅是緩解),如圖所示:            NIO會通過專門的Selector來管理請求,然後可由一個執行緒來處理請求,如圖所示:
     在NIO中,不得不提到的是關於抽象的資料容器ByteBuffer,ByteBuffer允許相同的資料在不同ByteBuffer之間共享而不需要再拷貝一次來處理。Slicing-ByteBuffer允許建立一個新的ByteBuffer通過暴露一個子邊界的形式共享原ByteBuffer的資料,這就大大減少了在資料處理過程中記憶體的copy(Zero-copy)。ByteBuffer通過一些索引來記錄讀寫的資訊,當你向其中寫資料時,它會自動跟蹤你寫到ByteBuffer的位置,類似,他也會自動跟蹤你讀的位置。而且ByteBuffer還提供了很多方法讓你切換讀寫模式(flip)或者清空(clear)或者壓縮(compact)等。      關於Selectors,NIOAPI通過selector來處理網路事件和資料。一個Channel代表一個網路連線。Selector的作用就是來決定這些Channel是否已準備好讀或者寫操作,一個selector可以處理很多連線請求,這就解決了為一個連線建立一個執行緒的問題。要想用一個selector需要以下步驟:      1.建立一個或多個selector用來給開啟的channels註冊。      2.當一個channel註冊後,就需要來確定哪種事件需要你監聽,通常有四種事件:      OP_ACCEPT       OP_CONNECT      OP_READ      OP_WRITE      3.當channels被註冊後,你需要呼叫Selector.select()方法來阻塞直到上述事件發生。      4.當方法沒有阻塞時,你會獲得所有SelectionKey例項,這些例項包含了已註冊channel的引用和其狀態,這樣你就可以做你的操作了。 三、Netty VS JavaNIO
1.跨平臺性和通用型      NIO某些底層的操作依賴於作業系統,因此,你寫的NIO程式有可能在windows上執行良好,但到了Linux可能會出現問題。  Java6和Java7對NIO提供了不同的解決方案,兩個API是不通用的。 2.拓展了ByteBuffer      Netty提供了對ByteBuffer的封裝類ByteBuf,拓展了JDK中ByteBuffer的功能,增強了易用性。 3.  資料拆分和聚集      很多時候我們想把資料分割成獨立的Bytebuffer來處理,比如Http協議Header放到一個buffer中,而Body放到另一個buffer中。很不幸,對於這種處理方式直到Java7才出現,而且如果處理不當,會極易造成OutOfMemoryError。      Scattering And Gathering:
4.解決了著名的epoll bug