【问题标题】:Netty IdleStateHandler times out when executor thread is busyNetty IdleStateHandler 在执行器线程忙时超时
【发布时间】:2012-10-05 13:06:53
【问题描述】:

我无法让 IdleStateHandler 在向服务器发送间隔“ping”时不超时。当执行器线程长时间忙于处理时会发生这种情况(对于同一通道)。

管道中的第一步是 IdleStateHandler,超时设置为 20 秒。

几个步骤后,管道将设置为 OrderedMemoryAwareThreadPoolExecutor,队列大小设置为 3 (maxChannelMemorySize)。

当执行器派出的工作线程处理很长时间(可能需要长达 90 秒)时,IdelStateHandler 似乎只能接收 3 条消息(messageReceived)。将执行程序中的队列大小更改为 30 将允许 IdleStateHandler 中的 30 个 messageReceived 调用。然后在 20 秒后超时。 channelIdle 在 GameServerHandler 中实现(最后一步)。

我对 Netty 还很陌生,所以很可能我还没有理解管道的概念——我的期望是消息总是在层之间传递。我希望每个传入的消息都会调用 IdleStateHandle,而不管执行器的队列大小,因为它是后来添加的。

我使用的是 netty 3.5.8 final。

我错过了什么?

OrderedMemoryAwareThreadPoolExecutor eventExecutor = new OrderedMemoryAwareThreadPoolExecutor(100, 3, 300);
Timer timer = new HashedWheelTimer();
...


pipeline.addLast("idleHandler", new IdleStateHandler(timer, 20, 0, 0));
...
pipeline.addLast("executionHandler", executionHandler);
pipeline.addLast("handler", new GameServerHandler());

【问题讨论】:

    标签: java netty ping


    【解决方案1】:

    ExecutionHandler 不应影响 IdleStateEvents 的生成。您需要了解的是,如果您处理 IdleStateEvents 的“逻辑”是在 GameServerHandler 中实现的,那将取决于您的 ExecutionHandler 的繁忙程度(或者更详细地说是它使用的 Executor)。

    所以我的建议是将 IdleStateEvents 的处理逻辑放在一个单独的 IdleAwareUpstreamHandler 实现中,并将其放在 ExecutionHandler 前面,这样它将由 IO-Thread 而不是通过 ExecutionHandler 处理。

    【讨论】:

    • 感谢您的回复。我尝试在执行程序之前添加一个“PingHandler”,但出现了相同的行为。似乎 IO 线程在 AbstractNioWroker (244) 中保持阻塞: int selected = SelectorUtil.select(selector);作为一种变通方法,我现在增加了队列大小。
    • 这毫无意义..您的代码是否有机会开源?我很想看看..
    • 不抱歉,我可以通过电子邮件将相关部分发送给您。问题很可能在我这边。尝试重现它的一种可能方法是像我对执行程序所做的那样设置一个管道,在处理程序中放置一个长时间的睡眠,并确保 IdleStateHandler 在执行程序线程在处理程序中处于睡眠状态时收到超过队列大小的消息。
    • 如果您可以编写一个“测试用例”来重现它,请在 netty 问题跟踪器中打开一个问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多