Java 使用Alpakka手动确认ActiveMQ消息

Java 使用Alpakka手动确认ActiveMQ消息,java,akka,activemq,akka-stream,alpakka,Java,Akka,Activemq,Akka Stream,Alpakka,我正在用Java实现Akka-Alpakka,用于从ActiveMQ队列消费和生成ActiveMQ队列。我可以成功地使用队列中的消息,但还不能实现应用程序级消息确认 我的目标是使用队列中的消息并将它们发送给另一个参与者进行处理。当该参与者完成处理后,我希望它能够控制ActiveMQ中消息的确认。这可能是通过向另一个可以进行确认的参与者发送消息、调用消息本身的确认函数或其他方式来实现的 在我的测试中,2条消息被放入AlpakkaTest队列,然后这段代码尝试使用并确认它们。但是,我看不到将Acti

我正在用Java实现Akka-Alpakka,用于从ActiveMQ队列消费和生成ActiveMQ队列。我可以成功地使用队列中的消息,但还不能实现应用程序级消息确认

我的目标是使用队列中的消息并将它们发送给另一个参与者进行处理。当该参与者完成处理后,我希望它能够控制ActiveMQ中消息的确认。这可能是通过向另一个可以进行确认的参与者发送消息、调用消息本身的确认函数或其他方式来实现的

在我的测试中,2条消息被放入AlpakkaTest队列,然后这段代码尝试使用并确认它们。但是,我看不到将ActiveMQ会话设置为CLIENT_ACKNOWLEDGE的方法,也看不到调用
m.ACKNOWLEDGE()与不调用
m.ACKNOWLEDGE()的行为有任何区别。因此,我认为信息仍然是自动确认的

有人知道在Java Akka系统中使用Alpakka为客户端确认和手动确认ActiveMQ消息配置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();
}

查看Alpakka JmsSourceStage的源代码,它已经为您确认了每个传入消息(它的会话是一个客户端Ack会话)。从我从消息来源可以看出,没有允许您确认消息的模式


您可以查看Alpakka的源代码。

更新:自Alpakka以来,在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);

(旁注:在相关的Streamz项目中,最近打开了一个允许应用程序级确认的应用程序。Streamz是旧的akka camel模块的替代品,与Alpakka一样,构建在akka Streams上。Streamz还具有Java API,并且作为外部连接器存在于Alpakka文档中。)

谢谢。ack要求更多地围绕着消息完整性,但以这种方式应用背压无疑是一个好信息。我也会调查一些。
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);
Timeout askTimeout = Timeout.apply(4, TimeUnit.SECONDS);

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