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 可用性
EmbeddedChannel 的readInbound()
和
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, 然後關閉連線.
ChunkedInput
和 ChunkedWriteHandler
ChunkedInput
有兩個新的方法; progress()
和 length()
返回資料傳輸的進度以及流的程度.
ChunkedWriteHandler
使用這個資訊通知 ChannelProgressiveFutureListener
.
SnappyFramedEncoder
和
SnappyFramedDecoder
這兩個類被改名為SnappyFrameEncoder
and SnappyFrameDecoder
. T老的類被標記為棄用, 實際上它們是新的類的子類.