Netty 4.1中的新变化和注意点
本文翻译自官方文档 New and noteworthy in 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.)
查看 Reference counted objects 得到更多信息 . 这个特性太重要了,所以也被增加回 4.0.14.
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()
方法得到.
更灵活的线程模型
一个新的 ChannelHandlerInvoker 加入, 允许用户对哪个线程处理handler方法有更多的控制
作为往 ChannelPipeline 中增加 ChannelHandler 时指定 EventExecutor 的替代,指定一个定制的 ChannelHandlerInvoker
实现可以实现更多的控制.
想了解更多的信息,可以参考 commit 132af3a .
EmbeddedChannel 可用性
EmbeddedChannel 的 readInbound()
和 readOutbound()
返回一个 特定类型的参数, 你不必将返回值在转型, 减少了单元测试代码的啰嗦.
能够使用 Executor
替换 ThreadFactory
一些应用要求用户运行他们的任务在一个指定的 Executor
. 而4.x在创建event loop时需要用户指定的是 ThreadFactory
,现在已经用 Executor
替换了.
关于这个改变的更多信息,你可以查看 pull request #1762 .
更友好的类加载器 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
包. - XmlFrameDecoder 允许处理XML文档流.
- JsonObjectDecoder 允许处理JSON对象流.
- 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老的类被标记为弃用, 实际上它们是新的类的子类.