1. 程式人生 > >Netty 4.1中的新變化和注意點

Netty 4.1中的新變化和注意點

本文帶你瞭解Netty 4.0到Netty 4.1的值得注意的改變和新特性.

題外話

儘管我們儘量保持向下相容,4.1 還是有一些和4.0不完全相容的地方. 請確保使用新的Netty版本重新編譯你的應用.
當你重新編譯你的應用時,你可以能看到一些棄用警告. 請依照修改建議來更正它們, 這樣當你升級到新的版本時會遇到較少的麻煩.

核心改變

Android支援

考慮到:

  • 移動裝置日益強大
  • 自 Ice Cream Sandwich版本後ADK中大部分NIO 和 SSLEngine的問題都被修復
  • 使用者很想在移動應用中重用它們的編解碼器和handler

我們決定官方的支援 Android (4.0 及以上版本) .
然而,我們並沒有一個為Android提供的測試套件. 如果你發現在Android使用的問題, 請提交一個 issue. 也請考慮貢獻Android的測試程式碼作為整個構建過程的一部分.

ChannelHandlerContext.attr(..) == Channel.attr(..)

Channel ChannelHandlerContext實現了 AttributeMap介面, 允許使用者附加一個或者多個屬性在它們上. 有時候使用者迷惑的是[Channel ChannelHandlerContext使用者自己的屬性儲存. 例如,即使你通過Channel.attr(KEY_X).set(valueX)設定一個屬性'KEY_X' , 你也不會通過ChannelHandlerContext.attr(KEY_X).get()得到這個屬性, 相反亦然. 這種行為不僅讓人迷惑,而且也浪費記憶體.

為了解決這個問題, 我們決定為每個Channel在內部只保留一個map. AttributeMap總是使用AttributeKey 作為它的主鍵. AttributeKey確保主鍵的唯一性, 這樣每個Channel不會有多餘一個的attribute map. 由於使用者會將他們自己的主鍵定義為 ChannelHandler的private static final 欄位 , 不會有重複的鍵值的擔憂.

Channel.hasAttr(...)

現在我們可以有效地檢查一個屬性是否存在.

更容易更精確的追蹤buffer leak

先前, 找到buffer洩漏並不容易,洩漏警告不太有幫助. 現在我們有了一個先進的洩漏報告機制,當開銷增加時會被啟用。(We now have an advanced leak reporting mechanism which can be enabled at the cost of increased overhead.)

PooledByteBufAllocator作為預設的buffer allocator

在 4.x 中, 儘管有一些功能侷限性, UnpooledByteBufAllocator 曾是預設的allocator. 現在 PooledByteBufAllocator 已經使用了很長一段時間了,而且我們有了先進的buffer洩漏追蹤機制,是時候把它作為預設的buffer allocator了.

現在PooledByteBufAllocator 是預設的buffer allocator.

全域性唯一的 channel ID

每個Channel都有一個唯一的ID,依據一下資訊產生:

  • MAC 地址 (EUI-48 or EUI-64),
  • 程序 ID,
  • System#currentTimeMillis()
  • System#nanoTime()
  • 一個隨機的 32-bit integer
  • 一個順序增加的32-bit integer.

Channe ID可以通過 Channel.id()方法得到.

更靈活的執行緒模型

EmbeddedChannel 可用性

EmbeddedChannelreadInbound()readOutbound() 返回一個 特定型別的引數, 你不必將返回值在轉型, 減少了單元測試程式碼的囉嗦.

1234567 EmbeddedChannel ch = ...;// BEFORE:FullHttpRequest req = (FullHttpRequest) ch.readInbound();// AFTER:FullHttpRequest req = ch.readInbound();

能夠使用Executor替換ThreadFactory

一些應用要求使用者執行他們的任務在一個指定的Executor. 而4.x在建立event loop時需要使用者指定的是ThreadFactory ,現在已經用Executor替換了.

更友好的類載入器 Class loader friendliness

在容器環境中一些型別如AttributeKey對應用程式來說不是太友好,現在沒有這個問題了.

ByteBufAllocator.calculateNewCapacity()

計算可擴充套件的ByteBuf容量的程式碼從AbstractByteBuf移到ByteBufAllocator, 因為ByteBufAllocator更方便的知道它管理的buffer的容量計算資訊.

新的編解碼和handler

  • Binary memcache protocol codec
  • Compression codecs
    * BZip2
    * FastLZ
    * LZ4
    * LZF
    
  • DNS protocol codec
  • HAProxy protocol codec
  • MQTT protocol codec
  • SPDY/3.1 support
  • STOMP codec
  • SOCKSx codec, 支援版本 4, 4a, 和 5; 檢視 socksx包.
  • IP filtering handlers

其它編解碼的改變

AsciiString

AsciiString是一個新的CharSequence實現, 包含的字元只佔1個位元組. 當你處理US-ASCII 或者 ISO-8859-1 字串時可以節省空間.

例如, HTTP 編解碼器和STOMP編解碼器使用AsciiString處理header name. 因為將AsciiString編碼到ByteBuf中不會有型別轉換的代價,比String型別有更好的效能.

TextHeaders

TextHeaders 提供了一個通用的資料結構,類似Http Header型別的字串 mutimap. HttpHeaders也用TextHeaders重寫.

MessageAggregator

MessageAggregator 為聚合多個小訊息成一個大訊息提供了通用的功能,就像HttpObjectAggregator實現的那樣. HttpObjectAggregator使用MessageAggregator進行了重寫.

HttpObjectAggregator更好的處理超出尺寸的訊息

在4.0中在客戶端傳送訊息前沒有辦法拒絕一個超過指定大小的HTTP 訊息,即使 100-continue header已經設定.
4.1中增加了一個可以override方法,叫做handleOversizedMessage, 因此使用者可以執行他想要的任務. 預設條件下, 它會返回一個 '413 Request Entity Too Large' response, 然後關閉連線.

ChunkedInputChunkedWriteHandler

ChunkedInput 有兩個新的方法; progress()length() 返回資料傳輸的進度以及流的程度. ChunkedWriteHandler使用這個資訊通知 ChannelProgressiveFutureListener.

SnappyFramedEncoderSnappyFramedDecoder

這兩個類被改名為SnappyFrameEncoder and SnappyFrameDecoder. T老的類被標記為棄用, 實際上它們是新的類的子類.