netty - 在什么情况下 ChannelPipeline 会删除其所有元素?
问题描述
我正在对 Netty 应用程序进行负载测试。
遵循Norman Mauer 的建议,该应用程序大量使用将任务提交给EventExecutor
可访问的 fromChannelHandlerContext#executor()
。(我以这种方式提交的任务保留了对提交时有效的引用。)ChannelHandlerContext
在观察应用程序中的奇怪行为后,我记录了ChannelHandlerContext.pipeline().toMap()
这些任务之一的输出,因为它由EventExecutor
on(定义)事件循环执行。
令人惊讶的是(对我而言)如此记录的管道是空的。
(我用更传统的channelRead
方法记录了管道,不用说它不是空的。)
我的应用程序中没有任何逻辑可以从ChannelPipeline
.
我没有关闭任何通道(客户端请求保持连接)。
我很确定我一定做错了什么——也许我不清楚 a 何时ChannelPipeline
超出范围或以其他方式“清除”。Netty 什么时候ChannelPipeline
清除?
解决方案
Netty 本身不会从 Pipeline 中移除处理程序。ChannelPipeline
当不再使用时(通道保持ChannelPipeline
关闭),GC 将其收集为常规 Java 对象。
所以要么你在你的代码中这样做(但你不这样做),要么管道被通道破坏。在您进行负载测试时,我的建议是下一个:
- 您在服务器上创建负载;
- 测试客户端无法处理足够的负载并关闭了一些连接(在高负载测试期间很常见);
- Netty 看到连接已关闭并删除了通道(及其管道)并使用 GC 收集;
- 结果,您仍然拥有引用已删除通道的上下文;
在负载下,这个 ChannelHandlerContext “被移除”,因此提交的写入任务在被事件循环运行时不能发生。
这是意料之中的。频道随时可能变得不可用。因此,如果您将任务委托给某个线程池,您应该检查通道是否仍然处于活动/可写状态,或者您可以ChannelFuture
从write()
操作中使用它。
更新:
根据您的需要,您有多种选择。您可以在实际写入之前检查通道是否可写:
if (ctx.channel().isWritable()) {
//write
}
您可以检查ChannelFuture
写操作的结果:
ChannelFuture cf = ctx.writeAndFlush();
//cf has a bunch of method + listeners that you can use
您也可以使用ChannelPromise
并覆盖所需的方法。
Netty 非常灵活并且提供了许多可能的流程。
推荐阅读
- swift - 如何将(hstack)多个视频与 AVMutableVideoComposition 并排组合?
- vb.net - 整数值后的尾随百分比字符
- kotlin - Kotlin 错误“索引超出范围异常”
- netlogo - 基于代理和基于个体的建模(Railsback 和 Grimm,2019)NetLogo 商业模式
- fpdf - 我在第 526 行的 FPDF 文件中不断出现致命错误
- javascript - 使用 javascript 将 html 页面转换为 pdf 时,我无法看到图像
- python - 使用单个 API 调用的 Django REST 框架序列化器字段
- google-bigquery - 是否可以在计划查询中执行“CREATE OR REPLACE TABLE foo_{@run_time|"%Y%m%d"} AS”?
- jit - 使用 numba jit 时格式化字符串
- r - R中的%in%是否有一致的替代方案?