文章目录
在生产环境中由于一些不明原因,导致 rabbitmq 重启,在 RabbitMQ 重启期间生产者消息投递失败,导致消息丢失,需要手动处理和恢复。于是,我们开始思考,如何才能进行 RabbitMQ 的消息可靠投递呢?特别是在这样比较极端的情况,RabbitMQ 集群不可用的时候,无法投递的消息该如何处理呢:
一、发布确认 SpringBoot 版本
1.1 确认机制方案
1.2 代码架构图
1.3 配置文件
在配置文件当中需要添加 spring.rabbitmq.publisher-confirm-type=correlated
NONE
禁用发布确认模式,是默认值CORRELATED
发布消息成功到交换器后会触发回调方法SIMPLE
经测试有两种效果,其一效果和 CORRELATED 值一样会触发回调方法,
其二在发布消息成功后使用 rabbitTemplate 调用 waitForConfirms 或 waitForConfirmsOrDie 方法等待 broker 节点返回发送结果,根据返回结果来判定下一步的逻辑,要注意的点是waitForConfirmsOrDie 方法如果返回 false 则会关闭 channel,则接下来无法发送消息到 broker
# 配置rabbitmq的连接信息
spring:
rabbitmq:
host: 192.168.159.128
port: 5672
username: admin
password: admin
publisher-confirm-type: correlated
mvc:
pathmatch:
matching-strategy: ant_path_matcher
1.4 添加配置类
package com.jz.springbootrabbitmq.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Gaoyonghao
* @date 2023-09-21 14:31
* @copyright Copyright (c) 2023 Gaoyonghao
*/
@Configuration
public class ConfirmConfig {
private static final String CONFIRM_EXCHANGE_NAME = "confirm.exchange";
private static final String CONFIRM_QUEUE_NAME = "confirm.queue";
// 声明业务Exchange
@Bean
public DirectExchange confirmExchange() {
return new DirectExchange(CONFIRM_EXCHANGE_NAME);
}
// 声明确认队列
@Bean
public Queue confirmQueue() {
return QueueBuilder.durable(CONFIRM_QUEUE_NAME).build();
}
// 声明确认队列绑定关系
@Bean
public Binding queueBinding(Queue confirmQueue, DirectExchange confirmExchange) {
return BindingBuilder.bind(confirmQueue).to(confirmExchange).with("key1");
}
}
1.5 消息生产者
package com.jz.springbootrabbitmq.controller;
import com.jz.springbootrabbitmq.service.MyCallback;
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;
import javax.annotation.PostConstruct;
/**
* @author Gaoyonghao
* @date 2023-09-21 15:28
* @copyright Copyright (c) 2023 Gaoyonghao
*/
@RestController
@RequestMapping(