簡體   English   中英

使用STOMP從ActiveMQ隊列讀取時的非阻塞事務

[英]Non-blocking transactions when reading from ActiveMQ queue with STOMP

我正在通過STOMP與ActiveMQ進行交互。 我有一個發布消息的進程,有多個訂閱和處理消息的進程(大約10個並行實例)。

閱讀消息后,我想確定如果由於某種原因我的應用程序失敗/崩潰,消息不會丟失。 很自然地,我轉向交易。 不幸的是,我發現,一旦某個使用者在交易中讀取了一條消息,以下所有消息就不會發送給其他使用者,直到交易結束。

測試案例: abc隊列中有100條消息。 如果我在兩個不同的瀏覽器選項卡中激活以下代碼,則第一個將在10秒后返回,第二個將在20秒后返回。

<?php
// Reader.php
$con = new Stomp("tcp://localhost:61613");
$con->connect();

$con->subscribe(
    "/queue/abc",
    array()
);

$tx = "tx3".microtime();
echo "TX:$tx<BR>";
$con->begin($tx);
$messages = array();
for ($i = 0; $i < 10; $i++) {
    $t = microtime(true);
    $msg = $con->readFrame();
    if (!$msg) {
        die("FAILED!");
    }
    $t = microtime(true)-$t; echo "readFrame() took $t MS to complete<BR>";
    array_push($messages, $msg);
    $con->ack($msg, $tx);
    sleep(1);
}
$con->abort($tx);

我在代碼方面缺少什么嗎? 有沒有一種方法可以配置ActiveMQ(或發送標頭),該方法將使事務從隊列中刪除該項目,允許其他進程使用其他消息,並且如果事務失敗或超時,則將該項目放回?

PS:我曾考慮過為每個閱讀過程創建另一個隊列-DetentionQueue,但如果可以選擇的話,我真的不願意這樣做。

您可能需要調整預訂的預取大小,以使ActiveMQ不會在客戶端2有機會獲得消息之前將隊列中的消息發送到客戶端1。 默認情況下將其設置為1000,因此最好針對您的用例進行調整。

您可以通過訂閱框架上的“ activemq.prefetchSize = 1”標頭設置預取大小。 有關所有框架選項,請參考ActiveMQ Stomp頁面。

暫無
暫無

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

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