使用 Netty 4.1 的内存感知通道处理

Memory-aware Channel handling with Netty 4.1

在 Netty 4 (3.x) 之前的版本中,有一种方法可以通过执行器内存感知通道处理,并使用 OrderedMemoryAwareThreadPoolExecutor 执行器命令执行操作给定 Channel。 3.x 中的 OrderedMemoryAwareThreadPoolExecutor 将负责为通道排序事件处理,即使它们可以由不同的线程执行,也可以限制 [=11= 使用的总内存].如果通道内存(由于排队的事件)超过某个阈值,事件的执行将被阻止,直到内存被释放。

但是在4.x中,没有这样的机制。新的线程模型确实提供了执行事件的排序(因为特定通道的事件由单个线程执行),但似乎没有办法限制单个 Channel 在任何EventExecutorGroups。这意味着,如果这不可能,发送到一个特定 Channel 的大量事件可能会耗尽服务器上的内存。虽然我还没有测试过这个事实,但我认为在这里问一下 Netty 是否确实如此 4.x 可能是值得的。

所以我的问题本质上是:

在 Netty 4.x 中使用 EventExecutorGroupChannelHandler 时,有没有办法限制单个 Channel 消耗的内存?

你是对的。这种情况是有可能的。

但是,Netty 为您的频道提供 ChannelOption.WRITE_BUFFER_WATER_MARK 选项。因此,当您向某个通道写入太快并且待处理消息队列超过 ChannelOption.WRITE_BUFFER_WATER_MARK 限制时,您正在写入的通道将变得不可写。所以你可以保护你的代码:

if (channel.isWritable()) {
}

if (ctx.channel().isWritable()) {
}

从而防止通道繁忙或事件消耗缓慢时内存耗尽。

您还可以更改 ChannelOption.AUTO_READ 用于生成事件并手动处理此事件的频道:

 ctx.channel().config().setAutoRead(false);

因此您的服务器将停止从生成过多事件的通道中读取事件。 Here is pull request 以这种方式演示。