2011-12-21 202 views
0

我在我的系統中有3個ThreadPoolExecutors。Netty線程被阻塞

一個用於Netty的主進程,另一個用於netty的工作進程,最後一個用於處理即席處理(向郵件服務器發送請求)。

ExecutorService bossExecutors = Executors.newFixedThreadPool(1, new 
ServerThreadFactory("netty-boss")); ExecutorService workerExecutors = 
Executors.newFixedThreadPool(10, new 
ServerThreadFactory("netty-worker")); 
      ChannelFactory factory = new NioServerSocketChannelFactory(
       bossExecutors, 
       workerExecutors, 
       Runtime.getRuntime().availableProcessors()); 

ExecutorService mailExecutor = Executors.newFixedThreadPool(40); 

直到mailExecutor開始向郵件服務器發出請求之後,它才能正常工作。在此之前,批量請求使用mailExecutor,通常向郵件服務器發送超過5000個請求,網絡線程被阻止。

我不明白爲什麼netty線程似乎會被阻止,因爲我已經分配了明確的線程池。在此期間,Netty甚至無法處理單個請求。

任何想法爲什麼發生或我做錯了什麼?

謝謝。

回答

0

這聽起來像是一個調度問題。在負載較重的情況下,您有40個線程,與處理Netty工作的availableProcessors線程數相比(創建工廠時您的availableProcessors()的數量是多少?)。

所以它可能只是因爲Netty線程太少,並且由於它們從來沒有被選中執行,與40個處理郵件工作的線程相比,它們正在捱餓。

也可能是由於某種原因,您的工作線程在郵件線程完成時被阻塞,可能是由於正在同步的某個共享對象(有一些隊列或郵件列表需要發送到netty線程需要寫入,以及郵件線程在發送時鎖定了哪些線程?)。

1

你能提供一個線程轉儲嗎?

jstack <pid> 

此外,你永遠不應該使用一個固定的線程池爲worker/poss線程池。使用一個緩存的,這樣你可以確保你永遠不會陷入任何飢餓。你應該在構造函數中用3參數指定工作者數。

+0

我使用工作人員將固定線程池更改爲緩存線程池count = Runtime.getRuntime()。availableProcessors() 但它似乎仍在發生。 這裏是線程轉儲:http://dl.dropbox.com/u/360993/jstack.txt 謝謝。 – 2011-12-22 20:07:02

+0

問題是發送到郵件服務器是一個阻止操作。所以你應該在發送處理程序的前面添加一個ExecutionHandler。否則,你將阻塞netty的IO線程。 – 2012-01-08 20:17:00