使用Alpakka消耗来自IBM JMS队列的消息

时间:2018-08-09 13:24:55

标签: java akka-stream alpakka

IBM队列(insert_queue)中有100条消息。我想消耗10个并存储在一个对象中,然后处理10个消耗的消息并等待一段时间,然后确认这10个消耗的消息。

我的示例代码:

public void consume(String queueName, int maxloadcount) throws Exception {

  Source<Message, KillSwitch> jmsSource =
            JmsConsumer.create(
                    JmsConsumerSettings.create(IBMQueueConnectionFactory.getMQQueueConnectionFactory())
                            .withQueue(queueName)
                            .withSessionCount(1)
                            .withBufferSize(10)
                            .withAcknowledgeMode(AcknowledgeMode.ClientAcknowledge()));

    CompletionStage<List<Message>> result =
            jmsSource
                    .take(maxloadcount)
                    .map(message -> {
                        return message;
                    })
                    .runWith(Sink.seq(), materializer);

    final List<Message> outMessages = result.toCompletableFuture().get(3, TimeUnit.SECONDS);
    for (Message outMsg : outMessages) {
        BytesMessage msg = (BytesMessage) outMsg;
        byte[] messageBody = msg.getBody(byte[].class);
        System.out.println(new String(messageBody));
    }
    TimeUnit.SECONDS.sleep(5);
    outMessages.stream().forEach(message -> {
        try {
           message.acknowledge();
        }
        catch (Exception e){
            e.printStackTrace();
        }
    });

}

不起作用

1 个答案:

答案 0 :(得分:0)

一旦消耗了给定数量的元素,

Source.take将完成流。您可能想要的是Source.throttle。以下示例每5秒最多向下游发送10条消息:

CompletionStage<List<Message>> result =
  jmsSource
    .throttle(10, java.time.Duration.ofSeconds(5L))
    .map(message -> {
      message.acknowledge();
      return message;
    })
    .runWith(Sink.seq(), materializer);

或者,看看Source.groupedWithin,它对流进行了分块,“分成在时间窗口内接收到的元素组,或者受给定元素数量的限制,无论先发生什么。”