RabbitMQ之消息回调

消息回调

ConfirmCallback:当消息到达交换机触发回调
ReturnsCallback:消息(带有路由键routingKey)到达交换机,与交换机的所有绑定键进行匹配,匹配不到触发回调

在这里插入图片描述

spring:
  rabbitmq:
    port: 5672
    host: 127.0.0.1
    username: guest
    password: guest
    publisher-confirm-type: correlated
    publisher-returns: true
#    template:
#      mandatory: true

package com.yzm.rabbitmq_08.config;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitConfig {

    /**
     * 定义rabbit template用于数据的接收和发送
     * connectionFactory:连接工厂
     */
    @Bean("rabbit")
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate template = new RabbitTemplate(connectionFactory);
        //数据转换为json存入消息队列
        template.setMessageConverter(new Jackson2JsonMessageConverter());

        /* 若使用 confirm-callback 或 return-callback,需要配置
         * publisher-confirm-type: correlated
         * publisher-returns: true
         */
        template.setConfirmCallback(confirmCallback());
        template.setReturnsCallback(returnCallback());
        /* 使用return-callback时必须设置mandatory为true,
         * 或者在配置中设置rabbitmq.template.mandatory=true
         */
        template.setMandatory(true);
        return template;
    }

    public static RabbitTemplate.ConfirmCallback confirmCallback() {
        return new RabbitTemplate.ConfirmCallback() {
            /**
             * 消息到达交换机触发回调
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                // ack判断消息发送到交换机是否成功
                System.out.println("回调id:" + correlationData.getId());
                if (ack) {
                    // 消息发送成功到达交换机
                    // ...
                    System.out.println("消息成功到达交换机");
                } else {
                    System.out.println("消息到达交换机失败");
                    System.out.println("错误信息:" + cause);
                }
            }
        };
    }

    public static RabbitTemplate.ReturnsCallback returnCallback() {
        return new RabbitTemplate.ReturnsCallback() {
            /**
             * 消息路由失败,回调
             * 消息(带有路由键routingKey)到达交换机,与交换机的所有绑定键进行匹配,匹配不到触发回调
             */
            @Override
            public void returnedMessage(ReturnedMessage returnedMessage) {
                System.out.println("交换机:" + returnedMessage.getExchange());
                System.out.println("路由键:" + returnedMessage.getRoutingKey());
                System.out.println("消息主体 : " + returnedMessage.getMessage());
                System.out.println("回复代码 : " + returnedMessage.getReplyCode());
                System.out.println("描述:" + returnedMessage.getReplyText());
            }
        };
    }

}
package com.yzm.rabbitmq_08.sender;

import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.UUID;

@RestController
public class Sender {

    @Resource(name = "rabbit")
    private RabbitTemplate rabbitTemplate;

    @GetMapping("/callback")
    public void callback() {
        // 全局唯一
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        String message = "Hello world!";
        System.out.println(" [ 生产者 ] Sent ==> '" + message + "'");
        rabbitTemplate.convertAndSend("callback.exchange", "callback.a.yzm", message, correlationData);
    }

    @GetMapping("/callback2")
    public void callback2() {
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        String message = "Hello world!";
        System.out.println(" [ 生产者 ] Sent ==> '" + message + "'");
        rabbitTemplate.convertAndSend("不存在的交换机", "callback.a.yzm", message, correlationData);
    }

    @GetMapping("/callback3")
    public void callback3() {
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        String message = "Hello world!";
        System.out.println(" [ 生产者 ] Sent ==> '" + message + "'");
        rabbitTemplate.convertAndSend("callback.exchange", "不存在的路由键", message, correlationData);
    }
}

交换机、队列以及绑定键,通过注解实现

package com.yzm.rabbitmq_08.receiver;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class Receiver {

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "callback_queue"),
            exchange = @Exchange(value = "callback.exchange"),
            key = {"callback.a.yzm", "callback.b.admin"}
    ))
    public void callbackA(Message message) {
        System.out.println(" [ 消费者@A号 ] Received ==> '" + new String(message.getBody()) + "'");
    }
}

访问http://localhost:8080/callback
运行结果:
在这里插入图片描述
消息正确到达交换机触发回调

访问http://localhost:8080/callback2
运行结果:
在这里插入图片描述
消息找不到交换机触发回调

访问http://localhost:8080/callback3
运行结果:
在这里插入图片描述
消息路由失败触发回调

监听路由失败回调

    /**
     * 应用:
     * 确认消息已经成功发送到队列中,如果未发送成功至队列,可进行消息的重新发送等操作。
     */
    @GetMapping("/ret")
    public void ret() throws IOException {
        Channel channel = rabbitTemplate.getConnectionFactory().createConnection().createChannel(false);
        //消息不可达,回调
        channel.addReturnListener(new ReturnListener() {
            @Override
            public void handleReturn(int replyCode, String replyText,
                                     String exchange, String routingKey,
                                     AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("replyCode:" + replyCode);
                System.out.println("replyText:" + replyText);
                System.out.println("exchange:" + exchange);
                System.out.println("routingKey:" + routingKey);
                System.out.println("properties:" + properties);
                System.out.println("body:" + new String(body));
            }
        });

        String message = "Hello world!";
        System.out.println(" [ 生产者 ] Sent ==> '" + message + "'");
        /**
         * Mandatory
         * 如果设置为ture:就表示的是要监听不可达的消息,然后进行处理
         * 如果设置为false:那么队列端会直接删除这个消息(默认值)
         */
       channel.basicPublish("callback.exchange", "不存在的路由键", true,
                MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
    }

在这里插入图片描述

相关链接

首页
上一篇:备用交换机
下一篇:Channel

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值