簡體   English   中英

單對多線程JMS生成器

[英]Single vs Multi-threaded JMS Producer

我想看看使用多線程生成器而不是單線程生成器會產生多大的時間差。 我在我的本地機器上設置了一個ActiveMQ,編寫了一個生成器類,它將在其構造函數中初始化並啟動JMS連接。 我將消息限制設置為3M,將所有消息推送到ActiveMQ大約需要50秒。 我發了一次3M字符串“hello world”。

然后我使用相同的生成器對象(一個連接但多個會話)並使用線程大小為8的ExecutorService運行它。 run方法中,我將3M除以8只是為了確保每個線程發送不超過375000條消息。 在這種情況下,推送所有消息大約需要60秒。

ExecutorService service = Executors.newFixedThreadPool(8);

    for (int i = 0; i < 8; i++) {

        service.execute(producer);
    }

然后我創建了8個生成器,每個生成器都有自己的連接,並使用ExecutorService或8號線程運行它們。 這次需要大約68秒來推送所有3M消息。

for (int i = 0; i < 8; i++) {
        service.execute(new Producer());
    }

我想知道,為什么單線程生產商會在這里表現更好? 我將每個場景運行了大約10次,但結果保持不變。

與Broker的連接使用單個TCP / IP連接來通過線路推送每條消息。 在大多數情況下,在同一連接上寫入生產者的多個線程沒有任何好處,因為當它們通過JMS層進入有線協議層時,所有調用將變為串行。 在您的情況下,由於線程調度加上鎖爭用加上管理線程池的開銷,需要更長的時間。

另一件需要考慮的事情是,根據您的生產者和發送到消息的目的地將同步發送到代理,生產者將阻止等待代理確認消息已存儲且不會丟失。 這會產生很大的開銷,但需要保證消息傳遞。 即使您使用多個連接,所有這些連接的吞吐量也會受到代理運行的磁盤速度的限制,因為它必須首先寫入所有持久性消息。

嘗試優化代碼實際上超出了StackOverflow的范圍,您需要進行一些研究並了解JMS代理的體系結構的含義以及您使用的代理的調優功能。 如果您的線程為每條消息打開一個新連接,那么這將是一個很大的性能損失,因為建立一個新連接是一項昂貴的操作,所以我建議調查JMS連接池,以此作為提高客戶端性能的方法。

對於您的情況,您可以查看異步發送或在事務中發送批量消息,以減少每次發送所花費的時間。

由於一些原因,多線程可能比線程慢。 一個是計算機的CPU是有限數字,因此不能同時運行所有線程使其變慢。 另一個原因是你也有一個有限的內存,導致線程需要更長的時間,因為它需要更多的內存。

以這種方式考慮多線程,你有一個可以最佳地適合3個走廊的走廊。 如果你的人數較少,那么人們需要更長時間才能讓所有人通過它。 另外,如果你試圖讓太多的人立刻通過走廊來堵塞,那么任何人都很難通過。

這就是多線程在這里以及在其他一些情況下可能會變壞的方式。

--------------------------------------編輯發生的事情:------ ----------------------------------------------

你在你的問題中說過你將單線程程序將3M除以8,這樣它就不會發送超過375000條消息。 但是當你多線程時,你發送的所有3M而不是375000? 如果這是真的,那么多線程比單線程慢的原因是因為java不能在同一時間執行不同的線程,它看起來像是在同時執行,因為它的運行速度,但它確實在你設置的所有線程。 它需要花一點時間在它之間切換。 幾納秒,因此需要更長的時間,因為即使多線程中的每個線程在單個線程中運行相同的數量,它也需要在線程之間切換,這使得它花費的時間非常少,從而加起來8運行所需的額外秒數。

從JMS應用程序的角度來看,您已將應用程序編寫為多線程; 多個會話,每個會話都有自己的JMS生成器對象,由不同的線程驅動。 假設您的應用程序沒有對諸如鎖等資源的爭用。

就發送消息的效率而言,取決於客戶端和服務器端部件如何有效地實現JMS提供者。 JMS實現中是否存在鎖定或爭用? 也許它試圖通過同一個套接字發送所有內容 - 在這種情況下存在爭用。 或許還有一些其他的鎖。

也許在底層隊列數據結構服務器端有一個鎖服務器端。

要回答您的問題,您需要詳細了解特定的JMS提供程序。

我猜測管理多個會話的開銷,他們與單一連接的訪問​​同步以及線程切換可能是原因。

為什么它應該在發送端使用多個線程更快地工作? 該行只有一個和最大數量的線程,我認為潛在的性能增益是兩個 - 當第一個發送數據時,第二個正在准備其數據並且它們交替切換。

我的錢是在Calanais概念上。 您是否嘗試在應用程序運行時對其進行監控? 像VisualVM這樣的簡單工具可以幫助您找出花費的時間。

您注意到的差異非常小,但我認為多線程處理器花費的時間更多,因為線程之間的cpu資源的並發性。 多線程處理器需要在線程之間共享cpu,這可能會花費時間和額外處理,有時會使您的進程變得更慢。 雖然單線程處理器不需要在沒有其他線程的情況下共享cpu,但它可以更有效地運行。 另一方面涉及用於每個線程的資源。 它們僅在內存中使用字符串,它們不訪問其他資源,如磁盤文件或數據庫或tcp端口。 在這種情況下,我認為,單線程進程將比多線程進程更快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM