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)。
求大神告知,是我理解的回呼設定錯誤,還是怎么回事?謝謝!!!!!!
uj5u.com熱心網友回復:
你理解的有誤,其實這個確認機制是生產者與rabbitmq的server的確認機制,這個只是說明rabbitmq是否收到了你發送的訊息uj5u.com熱心網友回復:
https://blog.csdn.net/qq315737546/article/details/54176560 你可以參考這篇文章轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/26696.html
標籤:中間件
上一篇:10萬塊錢能用什么ERP系統,求顧問解答(背包行業)
下一篇:weblogic記憶體溢位
