实现生产者投递消息到交换机的确认机制,以及消息由交换机投递到队列的错误返回机制。大家都知道是如下配置
具体实现代码如下
@Configuration
@Slf4j
public class RabbitConfig {
@Autowired
private RabbitTemplate rabbitTemplate;
// 表示当构造器RabbitConfig构造完成后 再调用此方法
@PostConstruct
public void rabbitTemplate() {
// 消息由生产者向RabbitMQ中投递,不论成功与否都触发此方法
rabbitTemplate.setConfirmCallback(((correlationData, ack, cause) -> {
log.info("ACK:" + ack);
if (ack){
log.info("------消息成功到达了Broker-------");
// 将消息状态改为投递成功
}else {
// 消息无法到达Broker
log.info("----------消息投递失败,无法到达Broker-------:{}",cause);
}
}));
}
}
自信满满的设置完成后想着运行下试试
@SpringBootTest
public class TestMq {
@Autowired
private MsgSender msgSender;
@Test
void testSend(){
msgSender.sendTransactionMessage(RabbitConstants.TEST_EXCHANGE,RabbitConstants.TEST_KEY,"发送报文","123");
}
}
咦 出现问题了
消费者都已经成功消费了,但是没有打印进入setConfirmCallback 。后续查了一些资料,整理后发出来,大致是这个意思:
如果在 Pulsar 生产者 API 中配置了 publisher-confirms: true,但是消息并没有进入 setConfirmCallback 方法中,但是配置了 publisher-confirm-type: correlated 后可以进入,可能是由于消息确认的机制不同导致的。
当配置 publisher-confirms: true 时,生产者将在成功将消息写入代理之后立即向应用程序返回确认消息。这种确认机制是在生产者本地完成的,因此在某些情况下,确认消息的回调可能无法被正确触发。
相比之下,publisher-confirm-type: correlated 提供了更细粒度的确认机制。使用相关确认语义时,生产者将等待所有副本都被成功写入代理之后才会向应用程序返回确认消息。因此,在使用相关确认语义时,确认消息的回调一定会在所有副本都成功写入代理后被触发,因为它涵盖了消息的所有冗余级别和副本。
因此,如果希望更可靠地接收确认消息回调,可以考虑使用 publisher-confirm-type: correlated 而不是 publisher-confirms: true。这将确保在所有副本都被成功写入代理后,确认消息的回调将被正确触发。
所以在配置中加上了publisher-confirm-type: correlated,再次运行代码,发现可以正常进入到ConfirmCallback 中
至此问题结束,希望可以帮助到你