我有一个Jersey应用程序,我在其中使用spring amqp库向rabbitMQ交换发布消息。我在我的兔子模板中使用CachingConnectionFactory,最初将Channel-Transacted设置为false。我注意到有些消息实际上没有发布到交换机,因此我将频道交易值更改为true。
在执行此操作时,我的发布功能开始花费500毫秒(当通道交易为假时为5毫秒)。我在这里缺少什么,因为500毫秒太多了。
作为替代方案,我尝试将publisherConfirms设置为true并添加了ConfirmCallback。我还没有对此进行基准测试,但是想知道这与通道交易相比是否会有更好的性能,因为此应用程序的唯一目的是在RabbitMQ中向交换发布消息?
另外,如果我选择publisherConfirms,我想在失败的情况下实现重试,或者至少能够抛出异常。通过频道交易,我会在出现故障时获得异常,但在这种情况下延迟很高。我不确定如何使用publisherConfirms实现重试。
我尝试重试发布商确认,但我的代码只是挂起。
这是我的代码:
CompleteMessageCorrelationData.java
public class CompleteMessageCorrelationData extends CorrelationData {
private final Message message;
private final int retryCount;
public CompleteMessageCorrelationData(String id, Message message, int retryCount) {
super(id);
this.message = message;
this.retryCount = retryCount;
}
public Message getMessage() {
return this.message;
}
public int getRetryCount() {
return this.retryCount;
}
@Override
public String toString() {
return "CompleteMessageCorrelationData [id=" + getId() + ", message=" + this.message + "]";
}
}
设置CachingConnectionFactory:
private static CachingConnectionFactory factory = new CachingConnectionFactory("host");
static {
factory.setUsername("rmq-user");
factory.setPassword("rmq-password");
factory.setChannelCacheSize(50);
factory.setPublisherConfirms(true);
}
private final RabbitTemplate rabbitTemplate = new RabbitTemplate(factory);
rabbitTemplate.setConfirmCallback((correlation, ack, reason) -> {
if (correlation != null && !ack) {
CompleteMessageCorrelationData data = (CompleteMessageCorrelationData)correlation;
log.info("Received nack for message: " + data.getMessage() + " for reason : " + reason);
int counter = data.getRetryCount();
if (counter < Integer.parseInt(max_retries)){
this.rabbitTemplate.convertAndSend(data.getMessage().getMessageProperties().getReceivedExchange(),
data.getMessage().getMessageProperties().getReceivedRoutingKey(),
data.getMessage(), new CompleteMessageCorrelationData(id, data.getMessage(), counter++));
} else {
log.error("Max retries exceeded for message: " + data.getMessage());
}
}
});
发布消息:
rabbitTemplate.convertAndSend(exchangeName, routingKey, message, new CompleteMessageCorrelationData(id, message, 0));
简而言之:
渠道交易我做错了,延迟是如此之高?
如果我要实施publisherConfirms,除了重试之外,我的方法有什么问题,并且它会比通道交易更好,考虑到除了向rabbitmq发布消息之外没有其他工作吗?
答案 0 :(得分:0)
正如您所发现的,交易成本高昂且性能显着下降;然而,500毫秒似乎很高。
我不相信出版商确认会有所帮助。在释放servlet线程之前,您仍然需要等待到代理的往返。当您发送大量消息然后等待所有确认返回时,发布者确认很有用;但是当你只发送一条消息然后等待确认时,它可能不会比使用交易快得多。
你可以尝试一下,但是代码有点复杂,特别是如果你想处理异常,你得到的是免费的&#34;与交易。