跳过导航

4.1 中的新增功能和值得注意的变更

您是否知道此页面是根据 Github Wiki 页面 自动生成的?您可以在 此处 自行改进!

本文档将引导您了解 Netty 4.1 和 4.0 之间的显着更改和新功能列表。

TL;DR

虽然我们尽力保持与 4.0 的向后兼容性,但 4.1 包含了多项可能与 4.0 无法完全向后兼容的新增功能。请确保针对新版本重新编译您的应用程序。

重新编译应用程序时,您可能会发现一些弃用警告。请务必使用建议的替代方案修复所有警告,以便在升级到下一个版本时减少麻烦。

核心更改

Android 支持

鉴于

  • 移动设备变得越来越强大,
  • 自 Ice Cream Sandwich 以来,ADK 中 NIO 和 SSLEngine 中最知名的
  • 用户显然希望在移动应用程序中重复使用他们的编解码器和处理程序,

我们决定正式支持 Android(4.0 或更高版本)。

但是,我们还没有针对 Android 的自动化测试套件。如果您发现任何与 Android 相关的问题,请随时提交问题。也请考虑为该项目做出贡献,以使 Android 测试成为构建过程的一部分。

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

ChannelChannelHandlerContext 都实现了接口 AttributeMap,以使用户能够为它们附加一个或多个用户定义的属性。有时让用户感到困惑的是,ChannelChannelHandlerContext 都有自己的用户定义属性存储。例如,即使通过 Channel.attr(KEY_X).set(valueX) 放置属性“KEY_X”,您也永远无法通过 ChannelHandlerContext.attr(KEY_X).get() 找到它,反之亦然。此行为不仅令人困惑,而且浪费内存。

为了解决此问题,我们决定在内部仅保留每个 Channel 一个映射。AttributeMap 始终使用 AttributeKey 作为其键。AttributeKey 确保每个键之间的唯一性,因此没有必要为每个 Channel 拥有多个属性映射。只要用户将其自己的 AttributeKey 定义为其 ChannelHandler 的私有静态 final 字段,就不会有重复键的风险。

Channel.hasAttr(...)

现在可以高效地检查属性是否存在。

更轻松、更精确的缓冲区泄漏跟踪

以前,很难找到缓冲区泄漏发生的位置,并且泄漏警告没有太大帮助。我们现在有一个高级泄漏报告机制,可以在增加开销的情况下启用。

有关更多信息,请参阅引用计数对象。由于其重要性,此功能也已移植到 4.0.14.Final。

PooledByteBufAllocator 作为默认分配器

在 4.x 中,UnpooledByteBufAllocator 是默认分配器,尽管它有其局限性。现在,PooledByteBufAllocator 已在野外使用了一段时间,并且我们已经有了先进的缓冲区泄漏跟踪机制,是时候将其作为新的默认值了。

全局唯一的通道 ID

现在,每个 Channel 都具有一个全局唯一的 ID,该 ID 由以下内容生成:

  • MAC 地址(EUI-48 或 EUI-64),最好是全球唯一的地址,
  • 当前进程 ID,
  • System#currentTimeMillis()
  • System#nanoTime()
  • 一个随机的 32 位整数,以及
  • 一个顺序递增的 32 位整数。

可以使用 Channel.id() 方法获取 Channel 的 ID。

EmbeddedChannel 可用性

EmbeddedChannel 中的 readInbound()readOutbound() 返回一个临时类型参数,因此您无需向下转换其返回值。这将大大减少单元测试代码的冗长性。

EmbeddedChannel ch = ...;

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

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

能够使用 Executor 而不是 ThreadFactory

某些应用程序要求用户在其给定的 Executor 中运行其任务。4.x 要求用户在创建事件循环时指定 ThreadFactory,但现在不再需要了。

有关此更改的更多信息,请参阅 请求拉取 #1762

类加载器友好性

某些类型(如 AttributeKey)对在容器环境中运行的应用程序不友好,但现在不再是这样了。

ByteBufAllocator.calculateNewCapacity()

计算扩展的 ByteBuf 的新容量的逻辑已从 AbstractByteBuf 移至 ByteBufAllocator,因为 ByteBufAllocator 更了解其管理的缓冲区的容量计算。

新的编解码器和处理程序

  • 二进制 memcache 协议编解码器
  • 压缩编解码器
    • BZip2
    • FastLZ
    • LZ4
    • LZF
  • DNS 协议编解码器
  • HAProxy 协议编解码器
  • MQTT 协议编解码器
  • SPDY/3.1 支持
  • STOMP 编解码器
  • 支持版本 4、4a 和 5 的 SOCKSx 编解码器;请参阅 socksx 包。
  • XmlFrameDecoder,它支持 XML 文档的流式传输。
  • JsonObjectDecoder,它支持 JSON 对象的流式传输。
  • IP 过滤处理程序

其他编解码器更改

AsciiString

AsciiString 是一个新的 CharSequence 实现,它只包含 1 字节字符。当您处理 US-ASCII 或 ISO-8859-1 字符串时,您会发现此类很有用。

例如,Netty 中的 HTTP 编解码器和 STOMP 编解码器使用 AsciiString 来表示标头名称。因为 AsciiString 在编码到 ByteBuf 时没有任何转换成本,所以它比使用 String 保证了更好的性能。

TextHeaders

TextHeaders 为类似 HTTP 标头的字符串 多重映射 提供了一个通用数据结构。HttpHeaders 也已使用 TextHeaders 重写。

MessageAggregator

MessageAggregator 提供了将多个小消息聚合到一个更大的消息中的通用功能,就像 HttpObjectAggregator 所做的那样。HttpObjectAggregator 也已使用 MessageAggregator 重写。

使用 HttpObjectAggregator 更好地处理超大消息

在 4.0 中,即使存在 100-continue 标头,也没有办法在客户端发送内容之前拒绝超大 HTTP 消息。

此版本添加了一个可覆盖的方法,称为 handleOversizedMessage,以便用户可以执行他或她首选的任务。默认情况下,它会响应“413 请求实体过大”响应并关闭连接。

ChunkedInputChunkedWriteHandler

ChunkedInput 有两个新方法;progress()length(),它们分别返回其传输的进度和流的总长度。 ChunkedWriteHandler 使用此信息通知 ChannelProgressiveFutureListener

SnappyFramedEncoderSnappyFramedDecoder

这两个类已重命名为 SnappyFrameEncoderSnappyFrameDecoder。旧类被标记为已弃用,它们实际上是新类的子类。

上次检索于 2024-07-19