簡體   English   中英

使用Alpakka手動確認ActiveMQ消息

[英]Manual Acknowledgement of ActiveMQ Messages with Alpakka

我正在努力實現Akka Alpakka,以便在Java中使用和生成ActiveMQ隊列。 我可以成功地從隊列中消耗,但我還沒有能夠實現應用程序級消息確認。

我的目標是使用隊列中的消息並將它們發送給另一個actor進行處理。 當該actor完成處理時,我希望它能夠控制ActiveMQ中的消息確認。 據推測,這可以通過向另一個可以進行確認的actor發送消息,在消息本身上調用確認函數或其他方式來完成。

在我的測試中,將2條消息放入AlpakkaTest隊列,然后此代碼嘗試使用並確認它們。 但是,我沒有看到將ActiveMQ會話設置為CLIENT_ACKNOWLEDGE的方法,並且我沒有看到有或沒有調用m.acknowledge();行為有任何差異m.acknowledge(); 因此,我認為消息仍然是自動確認的。

有沒有人知道為CLIENT_ACKNOWLEDGE配置ActiveMQ會話的可接受方式,並使用Alpakka在Java Akka系統中手動確認ActiveMQ消息?

相關測試功能是:

ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://0.0.0.0:2999"); // An embedded broker running in the test.

Source<Message, NotUsed> jmsSource = JmsSource.create(
    JmsSourceSettings.create(connectionFactory)
        .withQueue("AlpakkaTest")
        .withBufferSize(2)
);

Materializer materializer = ActorMaterializer.create(system); // `system` is an ActorSystem passed to the function.

try {
    List<Message> messages = jmsSource
        .take(2)
        .runWith(Sink.seq(), materializer)
        .toCompletableFuture().get(4, TimeUnit.SECONDS);

    for(Message m:messages) {
        System.out.println("Found Message ID: " + m.getJMSMessageID());

        try {
            m.acknowledge();
        } catch(JMSException jmsException) {
            System.out.println("Acknowledgement Failed for Message ID: " + m.getJMSMessageID() + " (" + jmsException.getLocalizedMessage() + ")");
        }
    }
} catch (InterruptedException e1) {
    e1.printStackTrace();
} catch (ExecutionException e1) {
    e1.printStackTrace();
} catch (TimeoutException e1) {
    e1.printStackTrace();
} catch (JMSException e) {
    e.printStackTrace();
}

此代碼打印:

Found Message ID: ID:jmstest-43178-1503343061195-1:26:1:1:1
Found Message ID: ID:jmstest-43178-1503343061195-1:27:1:1:1

更新 :自Alpakka 0.15起,確認模式可在JMS連接器中配置。 從鏈接的文檔:

Source<Message, NotUsed> jmsSource = JmsSource.create(JmsSourceSettings
    .create(connectionFactory)
    .withQueue("test")
    .withAcknowledgeMode(AcknowledgeMode.ClientAcknowledge())
);

CompletionStage<List<String>> result = jmsSource
    .take(msgsIn.size())
    .map(message -> {
        String text = ((ActiveMQTextMessage)message).getText();
        message.acknowledge();
        return text;
    })
    .runWith(Sink.seq(), materializer);

從版本0.11開始,Alpakka的JMS連接器不支持應用程序級消息確認。 Alpakka內部創建一個SessionCLIENT_ACKNOWLEDGE模式這里並確認每個消息這里在內部MessageListener API不會公開這些設置以進行覆蓋。

有一個打開的故障單 ,討論啟用下游確認基於隊列的源,但該故障單已暫停一段時間。

目前,您無法阻止Alpakka在JMS級別確認消息。 但是,這並不妨礙您向流添加一個階段,該階段將每個消息發送給actor進行處理,並將actor的回復用作背壓信號。 Akka Streams 文檔描述了如何使用mapAsyncaskSink.actorRefWithAck的組合來完成此Sink.actorRefWithAck 例如,要使用前者:

Timeout askTimeout = Timeout.apply(4, TimeUnit.SECONDS);

jmsSource
    .mapAsync(2, msg -> ask(processorActor, msg, askTimeout))
    .runWith(Sink.seq(), materializer);

(附注:在相關的Streamz項目中,有一個最近打開的票證允許應用程序級別確認.Streamz是舊的akka​​-camel模塊的替代品,和Alpakka一樣,是基於Akka Streams構建的.Streamz也有一個Java API並列出所述文檔Alpakka作為外部連接器)。

查看Alpakka JmsSourceStage的源代碼,它已經為您確認了每個傳入消息(並且它的會話是Client Ack會話)。 從我從源頭上可以看出,沒有允許你對消息進行確認的模式。

您可以在此處查看Alpakka的源代碼。

暫無
暫無

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

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