使用 Netty 4.1 的内存感知通道处理
Memory-aware Channel handling with Netty 4.1
在 Netty 4 (3.x) 之前的版本中,有一种方法可以通过执行器内存感知通道处理,并使用 OrderedMemoryAwareThreadPoolExecutor
执行器命令执行操作给定 Channel
。 3.x 中的 OrderedMemoryAwareThreadPoolExecutor
将负责为通道排序事件处理,即使它们可以由不同的线程执行,也可以限制 [=11= 使用的总内存].如果通道内存(由于排队的事件)超过某个阈值,事件的执行将被阻止,直到内存被释放。
但是在4.x中,没有这样的机制。新的线程模型确实提供了执行事件的排序(因为特定通道的事件由单个线程执行),但似乎没有办法限制单个 Channel
在任何EventExecutorGroup
s。这意味着,如果这不可能,发送到一个特定 Channel
的大量事件可能会耗尽服务器上的内存。虽然我还没有测试过这个事实,但我认为在这里问一下 Netty 是否确实如此 4.x 可能是值得的。
所以我的问题本质上是:
在 Netty 4.x 中使用 EventExecutorGroup
和 ChannelHandler
时,有没有办法限制单个 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 以这种方式演示。
在 Netty 4 (3.x) 之前的版本中,有一种方法可以通过执行器内存感知通道处理,并使用 OrderedMemoryAwareThreadPoolExecutor
执行器命令执行操作给定 Channel
。 3.x 中的 OrderedMemoryAwareThreadPoolExecutor
将负责为通道排序事件处理,即使它们可以由不同的线程执行,也可以限制 [=11= 使用的总内存].如果通道内存(由于排队的事件)超过某个阈值,事件的执行将被阻止,直到内存被释放。
但是在4.x中,没有这样的机制。新的线程模型确实提供了执行事件的排序(因为特定通道的事件由单个线程执行),但似乎没有办法限制单个 Channel
在任何EventExecutorGroup
s。这意味着,如果这不可能,发送到一个特定 Channel
的大量事件可能会耗尽服务器上的内存。虽然我还没有测试过这个事实,但我认为在这里问一下 Netty 是否确实如此 4.x 可能是值得的。
所以我的问题本质上是:
在 Netty 4.x 中使用 EventExecutorGroup
和 ChannelHandler
时,有没有办法限制单个 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 以这种方式演示。