当我在交换机上发布Nack时,我遇到了配置ReturnCallback的问题。这是我的工作:
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setPublisherConfirms(true);
connectionFactory.setPublisherReturns(true);
...
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
rabbitTemplate.setMandatory(true);
rabbitTemplate.setConfirmCallback(new MyMessageConfirmCallback());
rabbitTemplate.setReturnCallback(new MyMessageReturnCallback());
然后,当我发布消息时,我会向不存在的交换机发送消息
notificationProducerJmsTemplate.send("idontexist.exchange",
"idontexist.key",
messageToSend,
correlationData);
奇怪的是,我达到了MyMessageConfirmCallback
中定义的代码,但未达到MyMessageReturnCallback
中定义的代码,即使在第一个代码中,ack
的值为false
。
我正在使用RabbitMQ 3.4.2,这是我的maven依赖:
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>1.4.3.RELEASE</version>
</dependency>
最后但并非最不重要的,这是我在日志中可以看到的错误消息:
2015-03-26 16:29:24,094 GMT [pool-21-thread-1] (CachingConnectionFactory.java:281) ERROR connection.CachingConnectionFactory: Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'idontexist.exchange' in vhost '/', class-id=60, method-id=40)
有人看错了吗?是什么提示检查什么可以阻止调用ReturnCallback?
答案 0 :(得分:2)
这就是它在Rabbit Client中的工作原理:从代理启动AMQImpl.Close
以关闭当前Channel
。这是因为NOT_FOUND - no exchange 'idontexist.exchange' in vhost '/'
被视为严重错误(ChannelN#processAsync
):
if (method instanceof Channel.Close) {
asyncShutdown(command);
return true;
}
因此我们无法从那里到达} else if (method instanceof Basic.Return) {
。
PublisherCallbackChannelImpl
针对该案例调用handleNack
,因此 - ConfirmCallback
。