本文翻译自官方文档 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() 返回一个 特定类型的参数, 你不必将返回值在转型, 减少了单元测试代码的啰嗦.
EmbeddedChannel ch = ...;
// BEFORE:
FullHttpRequest req = (FullHttpRequest) ch.readInbound();
// AFTER:
FullHttpRequest req = ch.readInbound();
能够使用 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老的类被标记为弃用, 实际上它们是新的类的子类.