SpringBoot整合RabbitMq之生产者的发布确认

网上找了很多文章, 使用rabbitTemplate只有发布生产端的发布确认,却没有消费端的自动、手动应答,这里疑惑先保留,等我找到原因再更新。

什么是发布确认?

个人理解: rabbitmq发送消息到交换机、队列当中,不希望看到任何消息丢失或者发送失败的情况。所以就需要一种机制来实现发送消息的可靠性,发送者知道发送的消息是否成功,是否被消费。

RabbitMq提供了俩种方式来控制消息的发送可靠性

1. confirm        确认模式

        消息发送到交换机Exchange成功或者失败时, 回调

2. return          退回模式

        当消息发送给Exchange后,Exchange路由到Queue失败时处理

confirm模式:在配置文件中配置:

        publisher-confirm-type: correlated

在执行rabbitTemplate.send()或者messageProperties.setContentType()前,设置rabbitTemplate.setConfirmCallback,代码:

        /**
         * 消息发送到交换机Exchange失败时, 回调
         * 需要配置 publisher-confirm-type: correlated
         */
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /**
             *
             * @param correlationData  相关配置信息
             * @param ack   exchange交换机是否成功收到 消息,true 成功,false失败
             * @param cause  失败原因
             */

            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                if (ack) {
                    System.out.println("发送到交换机成功");
                    return;
                }
                System.out.println("发送到交换机失败");
            }
        });
        //fanout模式只往exchange里发送消息。分发到exchange下的所有queue
        rabbitTemplate.send("fanoutExchange5", "", new Message(message.getBytes("UTF-8"), messageProperties));
        return "message sended : " + message;

发送消息后,如果发送到了fanoutExchange5,ack为true,如果没找到,为false,都要执行confirm方法。

return 回退模式:当消息发送给Exchange后,Exchange路由到Queue失败时

        * 1. 如果消息没有路由到queue,默认丢弃消息(false)。        

        * 2.如果消息没有路由到queue,返回消息到ReturnsCallback(需要设置rabbitTemplate.setMandatory(true)。)
在配置文件中配置:

        publisher-returns: true

代码:

        /**
         * 回退模式:当消息发送给Exchange后,Exchange路由到Queue失败时,才执行setReturnsCallback
         *步骤:
         * 1. 开启回退模式:publisher-returns: true
         * 2. 设置ReturnsCallback
         * 3. 设置Exchange处理消息模式:
         *      1. 如果消息没有路由到queue,默认丢弃消息(false)。
         *      2.如果消息没有路由到queue,返回消息到ReturnsCallback(true)
         */
        //设置Exchange处理消息模式
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            @Override
            public void returnedMessage(ReturnedMessage returnedMessage) {
                System.out.println("执行了"+returnedMessage);
            }
        });
        //发消息
        rabbitTemplate.send("helloWorldqueue", new Message(message.getBytes("UTF-8"), messageProperties));
        return "message sended : " + message;

如果没有设置

        rabbitTemplate.setMandatory(true)

则为默认配置,丢弃消息。

整合俩个模式:

创建配置类,添加  @Configuration 注解。

package com.fan.testsendupdatell.configs;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@Slf4j
@Configuration
public class RabbitCallbackConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {
    @Bean
    RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
        return rabbitTemplate;
    }

    // 下边这样写也可以
    // @Autowired
    // private RabbitTemplate rabbitTemplate;
    // @PostConstruct
    // public void init() {
    //     rabbitTemplate.setMandatory(true);
    //     rabbitTemplate.setReturnCallback(this);
    //     rabbitTemplate.setConfirmCallback(this);
    // }

    /**
     *  消息发送到交换机Exchange失败时, 回调
     * @param correlationData  相关配置信息
     * @param ack   exchange交换机是否成功收到 消息,true 成功,false失败
     * @param cause  失败原因
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (!ack) {
            log.error("confirm==>发送到broker失败\r\n" +
                            "correlationData={}\r\n" + "ack={}\r\n" + "cause={}",
                    correlationData, ack, cause);
        } else {
            log.info("confirm==>发送到broker成功\r\n" +
                            "correlationData={}\r\n" + "ack={}\r\n" + "cause={}",
                    correlationData, ack, cause);
        }
    }

    /**
     * 回退模式:当消息发送给Exchange后,Exchange路由到Queue失败时,才执行setReturnsCallback
     *步骤:
     * 1. 开启回退模式:publisher-returns: true
     * 2. 设置ReturnsCallback
     * 3. 设置Exchange处理消息模式:
     *      1. 如果消息没有路由到queue,默认丢弃消息(false)。
     *      2.如果消息没有路由到queue,返回消息到ReturnsCallback(true)
     *      //设置Exchange处理消息模式  rabbitTemplate.setMandatory(true);
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText,
                                String exchange, String routingKey) {
        log.info("returnedMessage==> \r\n" + "message={}\r\n" + "replyCode={}\r\n" +
                        "replyText={}\r\n" + "exchange={}\r\n" + "routingKey={}",
                message, replyCode, replyText, exchange, routingKey);
    }
}

配置完成后,直接可以发送       

        rabbitTemplate.send()

自动根据配置执行模式方法。

你可能感兴趣的:(springBoot,RabbitMQ,rabbitmq,分布式)