2013-01-24 27 views
0

我們在CentOS 6.3上使用HornetQ 2.2.14。我們一直在遇到我們的應用服務器CPU使用率高的問題,並使用分析器將其縮小到我們的HornetQ消費者。Linux上的HornetQ消費者高CPU負載

具體而言,我們要求在空隊列快速連續此方法用約150消費者:

// Called about every 10ms per consumer. 
javax.jms.MessageConsumer.receive(10); 

這導致約2 NIO工作線程追溯Netty的,消耗2個的CPU核心50%左右,在我們空閒的Tomcat實例上。

PID USER  PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 
21939 tomcat 20 0 9061m 1.6g 16m R 55.4 21.2 1:06.88 java 
21777 tomcat 20 0 9061m 1.6g 16m S 47.6 21.2 1:29.40 java 
21777 tomcat 20 0 9061m 1.6g 16m S 7.3 21.2 1:33.41 java 
21763 tomcat 20 0 9061m 1.6g 16m S 6.6 21.2 1:28.84 java 
21682 tomcat 20 0 9061m 1.6g 16m S 4.3 21.2 0:26.70 java 

問題是,使用完全相同的代碼和Windows上的Tomcat配置,CPU內核處於空閒狀態。這導致我相信這是一個Linux/Netty/HornetQ問題。有沒有其他人看過這個,如果是的話,我該如何讓它消失?

Linux版本:CentOS的6.3 x64的 的Linux內核版本:Linux版本的2.6.32-279.19.1.el6.x86_64

這裏是2個的Java版本我有同樣的結果進行測試:

Java(TM) SE Runtime Environment (build 1.7.0_10-b18) 
Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode) 

Java(TM) SE Runtime Environment (build 1.6.0_38-b05) 
Java HotSpot(TM) 64-Bit Server VM (build 20.13-b02, mixed mode) 
+0

忘了補充,這裏有由簡標識的熱點: org.hornetq.core.client.impl.ClientConsumerImpl.receive()和 org.jboss.netty .channel.socket.nio.SelectorUtil.select() – Nobody

+0

通過切換HornetQ以使用阻塞IO沒有任何影響。現在不是2個使用CPU的NIO工作線程,而是使用2個阻塞IO工作線程消耗相同數量的CPU。一個客戶端線程和一個服務器線程。 – Nobody

+0

如果將超時值增加到30ms,會發生什麼情況。我問,因爲如果超時值接近實時時鐘的分辨率,可能會出現意想不到的事情,並且我記得時鐘在10ms左右的時候正常工作。 – parsifal

回答

2

國際海事組織你應該使用MessageListener ..或只是阻止更長的時間,如10秒...

...重複10毫秒是一個巨大的爆炸在您的系統上。尤其是客戶端每次都會向服務器發送回調。

讓消息系統爲您完成工作,即讓消息到達時給您打電話。如果您每10毫秒輪詢系統一次,則無法期待其他任何事情。

這是你的問題的罪魁禍首,如己指出:

consumer.receive(10); 

你算算,每一個消費者你在哪裏錘擊服務器與此接收(10)正在服務器發送100條消息您每個消費者每秒鐘說...我是空的。

一個接收(10)將進行往返以確保沒有傳輸中的消息。所以,你用空信息錘擊服務器。

根據您強制的參數,您的應用程序不應該運行良好。對於任何保證您接收(10)的消息解決方案在返回null之前都是空的。

+0

如果是這樣的話,爲什麼相同的代碼在所有CPU核心閒置的情況下都能正常工作?我希望HornetQ能夠同時處理幾百個消費者,而不需要大量的CPU資源。 – Nobody

+0

這個問題與HornetQ不同,你只需要10毫秒的時間請求一條新消息,而不是完成循環。 已知Linux內核在分配任務時更好,也許更高效的內核會讓你的錯誤代碼執行更多的執行?這當然只是一個猜測,但是你的代碼已經被破壞了......我可以向你保證這將是任何消息提供者的問題。 –

+0

你正在做什麼將等​​於這樣: while(true){db.select(0);等待(10); } 你在爲HornetQ指責你的CPU浪費? 這會浪費您實際使用的任何軟件上的CPU ......而不僅僅是一個消息傳遞提供程序。 –

1

儘管克萊伯特的回答有點難以忍受,但它最終是一個有效的案例。您可以輕鬆創建多個消息偵聽器,這些偵聽器將充當您的工作人員並允許JMS提供者調用它們。假設你的目標是某種類型的隊列,消息監聽器將被調用,分配負載相當分散,以允許多個線程處理處理。創建消息監聽器將允許JMS提供者在消息到達時調用它們,而不是等待客戶端使用消息。

每次調用接收方法時,它都會按照Clebert描述的方式行事(他應該知道,他是HornetQ的領先者)。

我不確定Netty HornetQ 2.2.14的版本是什麼,但是我在github上發現了一些關於非常相似的東西。也許你可以嘗試在應用程序中更新Netty的版本,看看是否有幫助?

https://github.com/netty/netty/issues/592

https://github.com/netty/netty/issues/582