springboot rabbitMQ 消息确认

本文基于上一篇博文springboot rabbitMQ 死信队列进行改动

消息发送确认

发送的消息怎么样才算失败或成功?如何确认?

RabbitTemplate.ReturnCallback

通过实现 ReturnCallback 接口,当消息路由不到队列时触发该回调。

RabbitTemplate.ConfirmCallback

通过实现 ConfirmCallback 接口,消息发送到 Broker 后触发回调,确认消息是否到达 Broker 服务器,即确认是否正确到达 Exchange 中。

代码示例

生产者

配置文件有所改动

spring.rabbitmq.host=192.168.130.128
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin

#开启消息确认机制
spring.rabbitmq.publisher-confirms=true
spring.rabbitmq.publisher-returns=true

#设置交换器名称
mq.config.exchange=direct_exchange
#设置队列的路由键
mq.config.queue.routing.key=test_key

实现ConfirmCallback接口

package com.sunyuqi.config;

import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;

@Component
public class MyConfirmCallback implements RabbitTemplate.ConfirmCallback {
    
    
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
    
    
        if (ack) {
    
    
            System.out.println("消息发送到exchange成功,id: "+ correlationData.getId());
        }
        else {
    
    
            System.out.println("消息发送到exchange失败,原因:  "+cause);
        }
    }
}

实现ReturnCallback接口

package com.sunyuqi.config;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyReturnCallback implements RabbitTemplate.ReturnCallback {
    
    
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
    
    
        String correlationId = message.getMessageProperties().getMessageId();
        String msg = new String(message.getBody());
        System.out.println("[消息ID:"+correlationId+" ,内容:"+ msg+"]发送失败, 应答码:"+replyCode+" 原因:"+replyText+" 交换机: "+exchange+"  路由键: "+routingKey);
    }
}

生产者类

package com.sunyuqi.routing;

import com.sunyuqi.config.MyConfirmCallback;
import com.sunyuqi.config.MyReturnCallback;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.UUID;

@Component
public class ProducerApp {
    
    
    @Autowired
    private RabbitTemplate rabbitTemplate;

    //exChange 交换器
    @Value("${mq.config.exchange}")
    private String exChange;

    //routingkey 路由键
    @Value("${mq.config.queue.routing.key}")
    private String routingKey;
    /**
     * 发送消息的方法
     * @param msg
     */
    @Autowired
    private MyConfirmCallback myconfirmCallback;

    @Autowired
    private MyReturnCallback myReturnCallback;

    public void send(Message msg){
    
    
        //向消息队列发送消息
        //参数1:交换器名称
        //参数2:路由键
        //参数3:消息
        this.rabbitTemplate.setMandatory(true);
        this.rabbitTemplate.setConfirmCallback(myconfirmCallback);
        this.rabbitTemplate.setReturnCallback(myReturnCallback);
        this.rabbitTemplate.convertAndSend(exChange,routingKey,msg,new CorrelationData(UUID.randomUUID().toString()));
    }
}

测试类

package sunyuqi;

import com.alibaba.fastjson.JSON;
import com.sunyuqi.SpringbootdemoApplication;
import com.sunyuqi.entity.Student;
import com.sunyuqi.routing.ProducerApp;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.UUID;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootdemoApplication.class)
public class QueueTest {
    
    

    @Autowired
    private ProducerApp producerApp;

    @Test
    public void test(){
    
    

        Student student = new Student();
        student.setId(1L);
        student.setAge(18);
        student.setName("jac");
        student.setSex("男");
        String s = JSON.toJSONString(student);
        Message message = MessageBuilder.withBody(s.getBytes())
                .setContentType(MessageProperties.CONTENT_TYPE_JSON)
                .setContentEncoding("utf-8")
                .setMessageId(UUID.randomUUID().toString()).build();
        producerApp.send(message);
    }
}

消费者代码不变,启动消费者引导类
运行测试类,消息发送成功,打印成功信息。
在这里插入图片描述
此时修改生产者配置文件

#设置交换器名称
mq.config.exchange=direct_exchange1

再次运行测试类,找不到交换机,即无法正确到达交换机
在这里插入图片描述
再次修改生产者配置文件

#设置交换器名称
mq.config.exchange=direct_exchange
#设置队列的路由键
mq.config.queue.routing.key=test_key1

能够正确到达交换机,但是无法路由到队列,触发ReturnCallback
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42494845/article/details/108818832