2012-10-15 50 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在處理程序中執行程序線程處於睡眠狀態時接收的隊列大小超過隊列大小。 –