rabbitmq 手工确认的问题?求大神告知

按照网上的demo,做了一个rabbitmq的例子,确认模式为手工确认(AcknowledgeMode.MANUAL),但是我的消息发送者,无论消费者是否调用channel.basicAck方法,都会执行到回调函数里。
代码:
配置文件:
@Configuration

public class RabbitConfig {

public static final String EXCHANGE = "exchange";

public static final String ROUTINGKEY = "will.message";

@Autowired
Receiver receiver;
@Bean

public ConnectionFactory connectionFactory() {

CachingConnectionFactory connectionFactory = new CachingConnectionFactory();

connectionFactory.setAddresses("10.120.1.148");

connectionFactory.setUsername("zhouyou");

connectionFactory.setPassword("zhouyou@163");

connectionFactory.setVirtualHost("/");

connectionFactory.setPublisherConfirms(true); //必须要设置

return connectionFactory;

}

@Bean

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

//必须是prototype类型

public RabbitTemplate rabbitTemplate() {

RabbitTemplate template = new RabbitTemplate(connectionFactory());

return template;

}

@Bean

public DirectExchange defaultExchange() {

return new DirectExchange(EXCHANGE);

}
@Bean

public Queue queue() {

return new Queue("will.message", true,false,false,null); //队列持久

}

@Bean

public Binding binding() {

return BindingBuilder.bind(queue()).to(defaultExchange()).with(RabbitConfig.ROUTINGKEY);
}

@Bean

public SimpleMessageListenerContainer messageContainer() {

SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());

container.setQueues(queue());

container.setExposeListenerChannel(true);

container.setMaxConcurrentConsumers(10);

container.setConcurrentConsumers(1);

container.setAcknowledgeMode(AcknowledgeMode.MANUAL); //设置确认模式手工确认

container.setMessageListener(receiver);
return container;

}

}
消费者receiver:
@Service
public class Receiver implements ChannelAwareMessageListener{
@Override
public void onMessage(Message message, Channel channel) throws Exception {
byte[] body = message.getBody();

System.out.println("receive msg : " + new String(body));
// channel.basicAck(message.getMessageProperties().getDeliveryTag(),false );
}
}
消息发送方sender:@Service

public class Sender implements RabbitTemplate.ConfirmCallback {

private RabbitTemplate rabbitTemplate;

/**

* 构造方法注入

/

@Autowired

public Sender(RabbitTemplate rabbitTemplate) {

this.rabbitTemplate = rabbitTemplate;

rabbitTemplate.setConfirmCallback(this); //rabbitTemplate如果为单例的话,那回调就是最后设置的内容

}

public void sendMsg(String content) {

CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());

rabbitTemplate.convertAndSend(RabbitConfig.EXCHANGE, RabbitConfig.ROUTINGKEY, content, correlationId);

}

/
*

* 回调

*/

@Override

public void confirm(CorrelationData correlationData, boolean ack, String cause) {

System.out.println(" 回调id:" + correlationData);

if (!ack) {

System.out.println("消息成功消费");

} else {

System.out.println("消息消费失败:" + cause);

}

}

}

测试方法
@Autowired
private Sender sender;
@RequestMapping("/getUserInfo")
@ResponseBody
public void getUserInfo() {
sender.sendMsg("will.message");
}
网页访问地址:
localhost:8080/getUserInfo。
现在问题就是:Receiver里面无论是否调用channel.basicAck(message.getMessageProperties().getDeliveryTag(),false ); 该方法,最后程序都会跑到Sender的confirm方法里面(即 public void confirm(CorrelationData correlationData, boolean ack, String cause) 方法,而且参数ack一直为true)。
求大神告知,是我理解的回调设置错误,还是怎么回事?谢谢!!!!!!
按照我自己的理解,设置为手工确认的时候,
那么需要调用channel.basicAck()方法,才会到回调函数里面去。求解答啊

手动确认一般是用来保持事物一致性,在确认客户端将消息消费后,程序回执给rabbitmq server端。server端将消息从server队列中删除。也就是不管你是否设置自动确认,消息一旦发出,都会到达client端

你那个只是消息发送到broker消息服务器的回调 不是业务的回调

楼主,你在Sender里面的实现的confirm方法是消息发送到MQ服务器后的回调方法,
作用是告知客户端程序本次发送的消息是否已经被MQ成功接收,客户端程序可以根据这个回调方法的状态参数进行相应的逻辑处理。
这里与Receiver(消费消息)没有关系。