RabbitMQ发送方消息确认机制

该博客详细介绍了如何在Spring Boot中配置RabbitMQ,包括设置生产者消息到达确认机制、死信交换机和队列。通过 ConfirmCallback 和 ReturnCallback 处理消息发送的确认与错误回调,确保消息的可靠传递。同时,定义了多个队列并进行了交换机与队列的绑定。
摘要由CSDN通过智能技术生成
@Slf4j
@Configuration
@ConditionalOnProperty(prefix = MqProperties.PREFIX, name = "enabled", havingValue = "true")
public class RabbitMqConfig {

    @Autowired
    private CachingConnectionFactory connectionFactory;

    // --------------------------------------------mq配置--------------------------------------------

    /**
     * 生产方的消息到达确认机制
     * ConfirmCallback 不管消息有没有正确到达exchange,都会被触发
     * --如果到达exchange,则confirm回调,ack=true
     * --如果未道道exchange,则confirm回调,ack=false
     * ReturnCallback 消息未正确到达队列时触发
     * --如果到达queue,则不会触发回调
     * --如果未到达queue,则触发回调
     * @return
     */
    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        rabbitTemplate.setMandatory(Boolean.TRUE);

        // 不论消息是否正确到达交换机,都会触发回调
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /**
             * @param correlationData 消息
             * @param ack 是否到达交换机的确认结果 true到达交换机 false未到达交换机
             * @param cause 未到达交换机的原因
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                if (!ack){
                    log.error("消息发送失败-未正确到达交换机\n消息:{}\n失败信息:{}", JSON.toJSONString(correlationData),cause);
                    // TODO 失败处理
                }
                
            }
        });

        // 只有消息未正确到达队列时,才会回调
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            /**
             * @param returnedMessage 消息
             * @param replyCode 失败码
             * @param replyText 失败原因
             * @param exchange 使用的交换机
             * @param routingKey 使用的路由键
             */
            @Override
            public void returnedMessage(Message returnedMessage, int replyCode, String replyText, String exchange, String routingKey) {
                log.error("消息发送失败-未正确到达交换机\n消息:{}\失败码:{}\n失败原因:{}\n交换机:{}\n路由键:{}",
                        JSON.toJSONString(returnedMessage),
                        replyCode,
                        replyText,
                        exchange,
                        routingKey);
                // TODO 重新发送
            }
        });
        return rabbitTemplate;
    }

    // --------------------------------------------交换机声明--------------------------------------------

    /**
     * 声明直连交换机
     * @return
     */
    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange(MQConstant.XXH_NOTICE_SERVICE);
    }

    /**
     * 声明死信交换机
     * @return
     */
    @Bean
    public DirectExchange dlxExchange() {
        return new DirectExchange(MQConstant.XXH_NOTICE_SERVICE_DLX);
    }

    // --------------------------------------------队列声明--------------------------------------------

    /**
     * 声明邮件队列
     * @return
     */
    @Bean
    public Queue emailQueue() {
        Map<String, Object> params = new HashMap<>(2);
        //声明当前队列绑定的死信交换机
        params.put("x-dead-letter-exchange", MQConstant.XXH_NOTICE_SERVICE_DLX);
        //声明当前队列的死信路由键
        params.put("x-dead-letter-routing-key", MQConstant.XXH_NOTICE_DLX_KEY);
        return QueueBuilder.durable(MQConstant.XXH_NOTICE_SERVICE_EMAIL_QUEUE).withArguments(params).build();
    }

    /**
     * 声明企微消息队列-文本消息队列
     * @return
     */
    @Bean
    public Queue wechatTextMsgQueue(){
        return new Queue(MQConstant.XXH_NOTICE_SERVICE_ENTERPRISEWECHAT_TEXTMSG_QUEUE,true);
    }

    /**
     * 声明短信队列
     *
     * @return
     */
    @Bean
    public Queue noteQueue() {
        return new Queue(MQConstant.XXH_NOTICE_SERVICE_NOTE_QUEUE, true);
    }

    /**
     * 声明死信队列
     *
     * @return
     */
    @Bean
    public Queue dlxQueue() {
        return new Queue(MQConstant.XXH_NOTICE_DLX_QUEUE);
    }

    // --------------------------------------------交换机与队列绑定--------------------------------------------

    /**
     * 绑定直连交换机和邮件队列
     * @return
     */
    @Bean
    public Binding bindingEmailQueue() {
        return BindingBuilder.bind(emailQueue()).to(directExchange()).with(MQConstant.XXH_NOTICE_SERVICE_EMAIL_KEY);
    }

    /**
     * 绑定直连交换机和企微文本消息队列
     * @return
     */
    @Bean
    public Binding bindingWechatTextMsgQueue(){
        return BindingBuilder.bind(wechatTextMsgQueue()).to(directExchange()).with(MQConstant.XXH_NOTICE_SERVICE_ENTERPRISEWECHAT_KEY_TEXT);
    }

    /**
     * 绑定死信交换机和死信队列
     * @return
     */
    @Bean
    public Binding dlcBinding() {
        return BindingBuilder.bind(dlxQueue()).to(dlxExchange()).with(MQConstant.XXH_NOTICE_DLX_KEY);
    }
    
    /**
     * 绑定交换机和短信队列
     * @return
     */
    @Bean
    public Binding bindingNoteQueue(){
        return BindingBuilder.bind(noteQueue()).to(directExchange()).with("xxh.notice.service.note_key");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值