如何處理客戶端中大量的執行緒

 常見問題 > 使用 Apache ActiveMQ Classic > 如何處理客戶端中大量的執行緒

如果您研究 ActiveMQ Classic 客戶端中的執行緒分配,您會注意到預設情況下,每個 Session 都會分配一個執行緒。這基本上意味著 Session 將使用其 ThreadPoolExecutor 來執行其任務。在 5.7 版本之前,這個執行器是無限制的,這可能導致在少數情況下發生 OOM 問題,即同一個 JVM 中有大量繁忙的 Session,可能會導致執行緒建立失控飆升。

在 5.7 版本中,我們將這個執行器限制為預設最多 1000 個執行緒,我們認為這對於大多數用例應該足夠了。如果大量 Session 處於繁忙狀態,每個 Session 都可能最終使用大量執行緒,並最終導致您的應用程式發生 OOM。您可以執行幾件事。首先,最明顯的事情是減少 Session 可以使用的最大執行緒限制,像這樣

ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
connectionFactory.setMaxThreadPoolSize(10);
Connection conn = connectionFactory.createConnection();
conn.start();

另一方面,這可能會導致單個 Session 用盡其最大執行緒數量的情況。在這種情況下,ThreadPoolExecutor 的預設行為是拋出異常,因此您會注意到它。解決此情況的方案是提供一個 rejected task handler,它將使執行與呼叫執行緒同步,像這樣

ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
connectionFactory.setRejectedTaskHandler(new ThreadPoolExecutor.CallerRunsPolicy());
Connection conn = connectionFactory.createConnection();
conn.start();

這將防止 ThreadPoolExecutor 在達到其限制時拋出異常。相反,它將在呼叫執行緒中執行 rejected task。

最後,您可以完全消除這些執行緒,您可以通過將 alwaysSessionAsync 屬性設定為 false 來實現

ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
connectionFactory.setAlwaysSessionAsync(false);
Connection conn = connectionFactory.createConnection();
conn.start();

但是,您需要記住,這種方法可能會影響整個系統的效能。

就這樣。在您的應用程式不太可能因為 JMS Session 建立的執行緒數量而出現問題的情況下,您可以使用所示的其中一種技術來處理它。一如既往,沒有適用於所有情況的萬能藥,因此請針對您的系統進行衡量和調整。

Apache、ActiveMQ、Apache ActiveMQ、Apache 羽毛標誌和 Apache ActiveMQ 專案標誌是 The Apache Software Foundation 的商標。 版權所有 © 2024,The Apache Software Foundation。 根據 Apache License 2.0 授權。