2012-10-15 47 views
1

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

流水线中的第一步是一个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()); 

回答

0

ExecutionHandler不应该影响IdleStateEvents的生成。你需要理解的是,如果你的处理IdleStateEvents的“逻辑”是在GameServerHandler中实现的,它将取决于你的ExecutionHandler是多么忙碌(或者更详细地说它是由它使用的Executor)。

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

+0

感谢您的回复。我试图在执行程序之前添加一个'PingHandler',但同样的行为出现。看起来像IO线程在AbstractNioWroker(244)中保持阻塞状态:int selected = SelectorUtil.select(selector);作为解决方法,我现在已经增加了队列大小。 –

+0

这是没有道理的..是你的代码开源吗?我很想看到它.. –

+0

没有抱歉,我可以通过电子邮件发送给你相关的部分。这个错误很可能在我身上。尝试重制它的一种可能的方法是像处理executor那样设置一个管道,在处理程序中放置一个长时间的睡眠,并确保IdleStateHandler在处理程序中执行程序线程处于睡眠状态时接收的队列大小超过队列大小。 –