在什么情况下,ChannelPipeline 的所有元素都会被移除?
Under what circumstances will a ChannelPipeline have all of its elements removed?
我正在对 Netty 应用程序进行负载测试。
该应用程序大量使用 submitting tasks to the EventExecutor
reachable from ChannelHandlerContext#executor()
, following Norman Mauer's recommendations。 (我以这种方式提交的任务保留了对提交时有效的 ChannelHandlerContext
的引用。)
在观察到应用程序中的奇怪行为后,我从其中一个任务中记录了 ChannelHandlerContext.pipeline().toMap()
的输出,因为它是由 EventExecutor
在(定义上)事件循环中执行的。
如此记录的管道是空的,令我惊讶的是(对我而言)。
(我从更传统的 channelRead
方法中记录了管道,不用说它不是空的。)
我的应用程序中没有任何从 ChannelPipeline
.
中删除项目的逻辑
我没有关闭任何通道(客户端请求保持连接)。
我很确定我一定是做错了什么——也许我不清楚 ChannelPipeline
何时超出范围或 "cleared"。 ChannelPipeline
什么时候被 Netty 清除?
Netty 本身不会从管道中删除处理程序。 ChannelPipeline
在不再使用时被 GC 收集为常规 Java 对象(通道持有 ChannelPipeline
已关闭)。
所以要么你在你的代码中这样做(但你没有),要么管道被通道破坏。
当您进行负载测试时,我的建议是:
- 您在服务器上创建负载;
- 测试客户端无法处理足够的负载并关闭一些连接(在高负载测试期间很常见的情况);
- Netty 看到连接已关闭并删除通道(和管道)并使用 GC 收集;
- 因此,您仍然拥有引用已删除频道的上下文;
Under load, this ChannelHandlerContext "becomes removed", and hence
the submitted write task cannot, when run by the event loop, take
place.
这是意料之中的。频道随时可能变得不可用。因此,如果您将任务委托给某个线程池,您应该检查通道是否仍然是 active/writable,或者您可以使用 write()
操作中的 ChannelFuture
。
更新:
根据您的需要,您有多种选择。您可以在实际写入之前检查通道是否可写:
if (ctx.channel().isWritable()) {
//write
}
写操作结果可以查看ChannelFuture
:
ChannelFuture cf = ctx.writeAndFlush();
//cf has a bunch of method + listeners that you can use
您也可以使用 ChannelPromise
并覆盖所需的方法。
Netty 非常灵活,提供了很多可能的流程。
我正在对 Netty 应用程序进行负载测试。
该应用程序大量使用 submitting tasks to the EventExecutor
reachable from ChannelHandlerContext#executor()
, following Norman Mauer's recommendations。 (我以这种方式提交的任务保留了对提交时有效的 ChannelHandlerContext
的引用。)
在观察到应用程序中的奇怪行为后,我从其中一个任务中记录了 ChannelHandlerContext.pipeline().toMap()
的输出,因为它是由 EventExecutor
在(定义上)事件循环中执行的。
如此记录的管道是空的,令我惊讶的是(对我而言)。
(我从更传统的 channelRead
方法中记录了管道,不用说它不是空的。)
我的应用程序中没有任何从 ChannelPipeline
.
我没有关闭任何通道(客户端请求保持连接)。
我很确定我一定是做错了什么——也许我不清楚 ChannelPipeline
何时超出范围或 "cleared"。 ChannelPipeline
什么时候被 Netty 清除?
Netty 本身不会从管道中删除处理程序。 ChannelPipeline
在不再使用时被 GC 收集为常规 Java 对象(通道持有 ChannelPipeline
已关闭)。
所以要么你在你的代码中这样做(但你没有),要么管道被通道破坏。 当您进行负载测试时,我的建议是:
- 您在服务器上创建负载;
- 测试客户端无法处理足够的负载并关闭一些连接(在高负载测试期间很常见的情况);
- Netty 看到连接已关闭并删除通道(和管道)并使用 GC 收集;
- 因此,您仍然拥有引用已删除频道的上下文;
Under load, this ChannelHandlerContext "becomes removed", and hence the submitted write task cannot, when run by the event loop, take place.
这是意料之中的。频道随时可能变得不可用。因此,如果您将任务委托给某个线程池,您应该检查通道是否仍然是 active/writable,或者您可以使用 write()
操作中的 ChannelFuture
。
更新:
根据您的需要,您有多种选择。您可以在实际写入之前检查通道是否可写:
if (ctx.channel().isWritable()) {
//write
}
写操作结果可以查看ChannelFuture
:
ChannelFuture cf = ctx.writeAndFlush();
//cf has a bunch of method + listeners that you can use
您也可以使用 ChannelPromise
并覆盖所需的方法。
Netty 非常灵活,提供了很多可能的流程。