什么是生产者confirm?
在上一篇文章<<消费者ack功能>>介绍了消费者的ack功能。接下来需要再介绍生产者的confirm机制;核心作用在与能确保生产者将消息发送到mq的channel中,这一过程需要确保消息不丢失就需要生产者给予mq一个确认发送消息的机制。confirm 模式最大的好处在于是异步的,一旦发布一条消息,生产者应用程序就可以在等信道返回确认的同时继续发送下一条消息,当消息最终得到确认之后,生产者应用便可以通过回调方法来处理该确认消息,如果RabbitMQ 因为自身内部错误导致消息丢失,就会发送一条 nack 消息, 生产者应用程序同样可以在回调方法中处理该 nack 消息。
下面演示核心的异步确认机制实战
yml配置类
spring:
rabbitmq:
#host为一般模式 若集群模式 将key换成addresses的形式
host: 192.168.9.104
port: 5672
#账号密码自行替换
username: admin
password: admin
publisher-confirm-type: correlated
publisher-returns: true
publisher-confirm-type 参数的可以参考 类 ConfirmType
SIMPLE: 使用同步的 Confirm 模式
CORRELATED: 使用异步的 Confirm 模式
NONE: 不使用 Confirm 模式
======================================》配置类
@Configuration
@Slf4j
public class RabbitConfiguration {
@Resource
ConnectionFactory connectionFactory;
/**
* 配置 RabbitTemplate
*
* @return RabbitTemplate
*/
@Bean
public RabbitTemplate createRabbitTemplate() {
RabbitTemplate rabbitTemplate = new RabbitTemplate();
rabbitTemplate.setConnectionFactory(connectionFactory);
// 设置开启Mandatory,才能触发回调函数,无论消息推送结果怎么样都强制调用回调函数
rabbitTemplate.setMandatory(true);
//确认消息送到交换机(Exchange)回调
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
log.info("[确认消息送到交换机(Exchange)结果][相关数据:{}][是否成功:{}][错误原因:{}]", correlationData, ack, cause);
}
});
// 确认消息送到队列(Queue)回调
// 当 Producer 成功发送消息到 RabbitMQ Broker 时,但是在通过 Exchange 进行匹配不到 Queue 时,Broker 会将该消息回退给 Producer 。
rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
@Override
public void returnedMessage(ReturnedMessage returnedMessage) {
log.info("[确认消息送到队列(Queue)结果:][回应码:{}][回应信息:{}][交换机:{}][路由键:{}][发生消息:{}]"
, returnedMessage.getReplyCode()
, returnedMessage.getReplyText()
, returnedMessage.getExchange()
, returnedMessage.getRoutingKey()
, returnedMessage.getMessage());
}
});
return rabbitTemplate;
}
}
================================》生产者代码
@Component
public class Producer06 {
@Resource
private RabbitTemplate rabbitTemplate;
public void syncSend(String id, String routingKey) {
// 创建 Message06 消息
Message06 message = new Message06();
message.setId(id);
// 同步发送消息
rabbitTemplate.convertAndSend(Message06.EXCHANGE, routingKey, message);
}
}
===========================》消费者
@Component
@RabbitListener(queues = Message06.QUEUE)
@Slf4j
public class Consumer06 {
@RabbitHandler
public void onMessage(Message06 message) {
log.info("[Message06 onMessage][线程编号:{} 消息内容:{}]", Thread.currentThread().getId(), message);
}
=========================》测试类
@Test
void syncSend() throws InterruptedException {
String id = UUID.randomUUID().toString();
producer06.syncSend(id, Message06.ROUTING_KEY);
log.info("[test producer06 syncSend][id:{}] 发送成功", id);
TimeUnit.SECONDS.sleep(2);
}
@Test
void syncSendFail() throws InterruptedException {
String id = UUID.randomUUID().toString();
// 发送一个不存在的 routingKey
producer06.syncSend(id, "aaa");
log.info("[test producer06 syncSend][id:{}] 发送成功", id);
TimeUnit.SECONDS.sleep(2);
}
以上的是生产者confirm机制实现的代码 若不了解rabbitmq的基本使用 建议先看看我前面对应的文章 文章链接:点我—>let’s go
若需完整代码 可识别二维码后 给您发代码。