zhouyou1314dyj 2016-10-29 05:31 采纳率: 0%
浏览 4400

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()方法,才会到回调函数里面去。求解答啊

  • 写回答

3条回答 默认 最新

  • brysj_123 2016-10-30 06:48
    关注

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

    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!