我正在使用Camel作为我的消息传递应用程序。在我的用例中,我有一个生产者(这里是RabbitMQ),而Consumer是一个bean。
from("rabbitmq://127.0.0.1:5672/exDemo?queue=testQueue&username=guest&password=guest&autoAck=false&durable=true&exchangeType=direct&autoDelete=false")
.throttle(100).timePeriodMillis(10000)
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
MyCustomConsumer.consume(exchange.getIn().getBody())
}
});
显然,当autoAck为false时,在process()执行完成时发送确认(如果我错了,请纠正我)
现在我不想承认process()执行何时完成,我想在稍后阶段完成。我的MyCustomConsumer中有BlockingQueue
,其中consume()放置消息,而MyCustomConsumer有不同的机制来处理它们。我想在MyCustomConsumer完成处理来自BlockingQueue
的消息时确认消息。我怎样才能做到这一点?
答案 0 :(得分:1)
在处理来自BlockingQueue的邮件后,您可以考虑使用camel AsyncProcessor API来调用回调。
答案 1 :(得分:1)
我碰到了同样的问题。
Camel RabbitMQConsumer.RabbitConsumer实现
consumer.getProcessor().process(exchange);
long deliveryTag = envelope.getDeliveryTag();
if (!consumer.endpoint.isAutoAck()) {
log.trace("Acknowledging receipt [delivery_tag={}]", deliveryTag);
channel.basicAck(deliveryTag, false);
}
所以它只是期待一个同步处理器。 例如,如果将其绑定到seda路由,则进程方法会立即返回,并且您几乎可以回到autoAck情况。
我的理解是我们需要让我们自己的RabbitMQ组件做类似
的事情consumer.getAsyncProcessor().process(exchange, new AsynCallback() {
public void done(doneSync) {
if (!consumer.endpoint.isAutoAck()) {
long deliveryTag = envelope.getDeliveryTag();
log.trace("Acknowledging receipt [delivery_tag={}]", deliveryTag);
channel.basicAck(deliveryTag, false);
}
}
});
即使这样," doneSync"的语义也是如此。参数不清楚。我认为它只是一个标记,用于确定我们是否正在处理真正的异步处理器或自动封装成异步处理器的同步处理器。
也许有人可以验证或无效此解决方案?
是否有更轻/更快/更强的替代方案?
或者这可以被建议作为RabbitMQConsumer的默认实现吗?