springboot integrates rabbitmq fallback message

fallback message

When only the producer confirmation mechanism is enabled, the switch will directly send a confirmation message to the message producer after receiving the message.
If the message is found to be unroutable, the message will be discarded directly. At this time, the producer does not know Messages are dropped for this event. So how do I get messages that cannot be routed to help me find a way to deal with them? At least let me know, so I can handle it myself. By setting the mandatory parameter, the message can be returned to the producer when the destination is unreachable during message delivery.
Simply put, if the RoutingKey is wrong and the switch is normal, a message will be thrown directly.

1.yml configuration

spring:
  rabbitmq:
    host: 192.168.64.137
    port: 5672
    username: guest
    password: 123
    virtual-host: /
#    publisher-confirm-type: correlated
#    开启发布确认类型
#    ⚫ NONE
#    禁用发布确认模式,是默认值
#    ⚫ CORRELATED
#    发布消息成功到交换器后会触发回调方法
#    ⚫ SIMPLE (发一条确认一条,不用)
#    经测试有两种效果,其一效果和 CORRELATED 值一样会触发回调方法,
#    其二在发布消息成功后使用 rabbitTemplate 调用 waitForConfirms 或 waitForConfirmsOrDie 方法
#    等待 broker 节点返回发送结果,根据返回结果来判定下一步的逻辑,要注意的点是
#    waitForConfirmsOrDie 方法如果返回 false 则会关闭 channel,则接下来无法发送消息到 broker
    publisher-confirms: true
#    路由不出去的消息会回退
    publisher-returns: true

2. Configuration class

package com.cherry.rabbitmqttl.config;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类 发布确认(高级)
 */
@Configuration
public class ConfirmConfig {
    
    
    // 交换机
    public static final String CONFIRM_EXCHANGE_NAME = "confirm_exchange";
    // 队列
    public static final String CONFIRM_QUEUE_NAME = "confirm_queue";
    // routingKey
    public static final String CONFIRM_ROUTING_KEY = "key1";

    // 声明交换机
    @Bean("confirmExchange")
    public DirectExchange confirmExchange(){
    
    
        return new DirectExchange(CONFIRM_EXCHANGE_NAME);
	}

    // 队列
    @Bean("confirmQueue")
    public Queue confirmQueue(){
    
    
        return QueueBuilder.durable(CONFIRM_QUEUE_NAME).build();
    }


    @Bean
    public Binding queueBindingExchange(@Qualifier("confirmQueue")Queue confirmQueue,
                                        @Qualifier("confirmExchange")DirectExchange confirmExchange){
    
    
        return BindingBuilder.bind(confirmQueue).to(confirmExchange).with(CONFIRM_ROUTING_KEY);
    }

3. Producer

package com.cherry.rabbitmqttl.controller;

import com.cherry.rabbitmqttl.config.ConfirmConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 测试确认开始发消息
 */
@Slf4j
@RequestMapping("/confirm")
@RestController
public class ConfirmProductController {
    
    

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 交换机错误时交换机会显示交换机未收到消息的错误信息,
     * routingkey错误时会显示交换机收到消息
     * 发送消息内容,你好啊key1
     * Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'confirm_exchange1' in vhost '/', class-id=60, method-id=40)
     * 交换机还未收到 id 为:ID=1消息,由于原因:channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'confirm_exchange1' in vhost '/', class-id=60, method-id=40)
     * 送消息内容,你好啊key12
     * 交换机已经收到 id 为:ID=2的消息
     * @param message
     */
    // 发消息
    // ID唯一标识
    // routingkey错误时没法获得失败回调
    @GetMapping("/sendMsg/{message}")
    public void sendMessage(@PathVariable String message){
    
    
        // 正常发送消息: 交换机和队列都收到了
        CorrelationData correlationData3 =  new CorrelationData("ID=0");
        rabbitTemplate.convertAndSend(ConfirmConfig.CONFIRM_EXCHANGE_NAME,
                ConfirmConfig.CONFIRM_ROUTING_KEY,
                message,
                correlationData3);
        log.info("发送消息内容,{}", message + "key0" );
        log.info("______________________________________________________________________");

        // 交换机错误发送消息:交换机未收到,队列未收到
        CorrelationData correlationData1 =  new CorrelationData("ID=1");
        rabbitTemplate.convertAndSend(ConfirmConfig.CONFIRM_EXCHANGE_NAME+1,
                ConfirmConfig.CONFIRM_ROUTING_KEY + "key1",
                message + "key1",
                correlationData1);
        log.info("发送消息内容,{}", message + "key1");
        log.info("______________________________________________________________________");

        // routingkey错误发送消息:交换机收到,队列未收到
        CorrelationData correlationData2 =  new CorrelationData("ID=2");
        rabbitTemplate.convertAndSend(ConfirmConfig.CONFIRM_EXCHANGE_NAME,
                ConfirmConfig.CONFIRM_ROUTING_KEY + "2",
                message + "key12",
                correlationData2);
        log.info("发送消息内容,{}", message + "key12");


    }



}

4. Consumers

package com.cherry.rabbitmqttl.consumer;

import com.cherry.rabbitmqttl.config.ConfirmConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class ConfirmConsumer {
    
    
    @RabbitListener(queues = ConfirmConfig.CONFIRM_QUEUE_NAME)
    public void receiveConfirm(Message message){
    
    
        String mesg = new String(message.getBody());
        log.info("接收到的队列confirm.queue消息:{}", mesg);
    }
}

5. Rollback callback function

package com.cherry.rabbitmqttl.confirmcallback;

import lombok.extern.slf4j.Slf4j;
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.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * 感知不能正常消费的消息回调
 */
@Component
@Slf4j
public class MyCallBack implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback {
    
    
    // 注入
    @Autowired
    private RabbitTemplate rabbitTemplate;

    //  @PostConstruct注入功能再Autowired注入后注入
    @PostConstruct
    public void init(){
    
    
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    /**
     * 交换机不管是否收到消息的一个回调方法
     * CorrelationData
     * 消息相关数据
     * ack
     * 交换机是否收到消息
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, java.lang.String cause) {
    
    
        String id=correlationData!=null?correlationData.getId():"";
        if(ack){
    
    
            log.info("交换机已经收到 id 为:{}的消息",id);
        }else{
    
    
            log.info("交换机还未收到 id 为:{}消息,由于原因:{}",id,cause);
        }
    }


    // 可以再当消息传递过程中不可路由时将消息返回给生产者(routingKey错误)
    // 只有不可达目的时候,才进行回退
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
    
    
        log.error("消息{},被交换机{}退回,退回的原因:{},路由Key{}",
                new String(message.getBody()),
                exchange,
                replyText,
                routingKey);
    }


}

6. pom dependency

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
    </parent>
    <groupId>com.cherry</groupId>
    <artifactId>rabbitmqttl</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>rabbitmqttl</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--RabbitMQ 依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--RabbitMQ 测试依赖-->
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Guess you like

Origin blog.csdn.net/m0_49382941/article/details/129794667