我们的管道使用具有10个线程的NIO工作组。
我们的管道设置如下:
ch.pipeline().addLast(new IdleStateHandler(0, 0, 10, TimeUnit.Seconds))
.addLast(sslHandler)
.addLast(businessLogicHandler)
.addLast(defaultEventExecutorWith5Threads, exceptionHandler)
ExceptionHandler对write()不执行任何操作,除了再次调用write并等待promise以便它可以检测到任何失败。它看起来像这样:
ctx.write(msg, promise.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
if (!future.isSuccess()) {
// Handle write exception here...
}
}
}))
我们看到exceptionHandler和businessLogicHandler之间大约有10秒的零星延迟。换句话说,我们称之为:
channel.write(message);
它会立即显示在exceptionHandler中,然后需要10秒才能进入businessLogicHandler。然而,延迟并非100%一致。只是非常频繁。
我们注意到,如果我们调用channel.writeAndFlush(message),这似乎可以缓解这个问题,但我无法理解为什么会这样。我的理解是:
write()将向管道发送一条消息,最后在管道前面缓冲它。如果缓冲区填满,netty会自动将其推到电线上。
flush()将强制缓冲区之前的缓冲区刷新()。
在这种情况下,我无法理解为什么flush会在消息传播过程中产生任何影响。我能理解,如果我们没有看到消息通过网络传递。
更新: 延迟完全对应于IdleStateHandler中指定的超时。在当前示例中,在随机处理程序中向下传播管道块正好10秒。如果将超时设置为30秒,则随机阻塞随机发生30秒。
更新: 我开始认为这可能与此有关: https://github.com/netty/netty/commit/f44f3e7926f1676315ae86d0f18bdd9b95681d9f
更新: 我已经为Netty开了一个问题,因为我认为之前评论中描述的竞争条件仍然存在。 https://github.com/netty/netty/issues/7719