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

zhouyou1314dyj 2016-10-29 01:27:40
1:按照网上的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)。
求大神告知,是我理解的回调设置错误,还是怎么回事?谢谢!!!!!!
...全文
3265 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
LongJi007 2018-08-23
  • 打赏
  • 举报
回复
https://blog.csdn.net/qq315737546/article/details/54176560 你可以参考这篇文章
garychenqin 2017-03-26
  • 打赏
  • 举报
回复
你理解的有误,其实这个确认机制是生产者与rabbitmq的server的确认机制,这个只是说明rabbitmq是否收到了你发送的消息

1,220

社区成员

发帖
与我相关
我的任务
社区描述
企业软件 中间件技术
社区管理员
  • 中间件
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧