springboot rabbitMQ message confirmation

This article is based on the previous blog post springboot rabbitMQ dead letter queue to make changes

Message sending confirmation

How does the sent message count as a failure or success? How to confirm?

RabbitTemplate.ReturnCallback

By implementing the ReturnCallback interface, the callback is triggered when the message is not routed to the queue.

RabbitTemplate.ConfirmCallback

By implementing the ConfirmCallback interface, a callback is triggered after the message is sent to the Broker to confirm whether the message has reached the Broker server, that is, whether it has arrived in the Exchange correctly.

Code example

Producer

Configuration file has changed

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

Implement the ConfirmCallback interface

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);
        }
    }
}

Implement ReturnCallback interface

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);
    }
}

Producer class

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()));
    }
}

Test class

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);
    }
}

The consumer code is unchanged, start the consumer boot class and
run the test class, the message is sent successfully, and the success message is printed.
Insert picture description here
Modify the producer configuration file at this time

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

Run the test class again, but the switch cannot be found, that is, the switch cannot be reached correctly.
Insert picture description here
Modify the producer configuration file again

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

Can reach the switch correctly, but cannot be routed to the queue, triggering ReturnCallback
Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_42494845/article/details/108818832