发布确认模式

   在生产环境中由于一些不明原因,导致rabbitmq重启,在RabbitMQ重启期间生产者消息投递失败,导致消息丢失,需要手动处理和恢复。于是,我们开始思考,如何才能进行RabbitMQ的消息可靠投递呢?特别是在这样比较极端的情况,RabbitMQ集群不可用的时候,无法投递的消息该如何处理呢?

 代码框架:

需要一个回调接口,当消息发出去后交换机没有被接收,就会触发回调接口,然后将消息重发。

# 交换机确认消息
spring.rabbitmq.publisher-confirm-type=correlated
# 开启回退消息
spring.rabbitmq.publisher-returns=true

需要开启两个配置,第一个是确认机制,第二个是回退即通知生产者消息发送的情况

代码实现

1、配置类

@Component
@Slf4j
public class MyCallBack implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback{

    @Autowired
     private RabbitTemplate rabbitTemplate;

    // 注入
    @PostConstruct
    public void init(){
        rabbitTemplate.setConfirmCallback(this);
    }
    /**
     * 交换机确认回调的方法
     * 1、发消息 交换机接收到了  回调
     *     1.1 correlationData 保存回调消息的id和相关信息
     *     1.2 交换机收到消息  ack = true
     *     1.3 原因 cause
     * 2、发消息 交换机接收失败了  回调
     *     ack = false
     * 3、第一个参数是从消费者中来的
     * @param correlationData
     * @param ack
     * @param s
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String s) {

        String id = correlationData != null ? correlationData.getId() : "";
        if(ack){
            log.info("交换机已经收到id为:{}的消息",id);
        }else {
            log.info("交换机还未收到id为:{}的消息,由于原因:{}",id,s);
        }
    }

    /**
     * 回退接口的方法
     * 可以将消息传递过程中不可达目的地时将消息返回给生产者
     * 只有将消息不可达的时候才进行回退
     * @param message
     * @param i
     * @param replyText
     * @param exchange
     * @param routingKey
     */
    @Override
    public void returnedMessage(Message message, int i, String replyText, String exchange, String routingKey) {
        log.info("消息{}被交换机{}回退,退回原因{},路由key{}",
                new String(message.getBody()),exchange,replyText,routingKey);

    }
}

2、生产者

/**
 * 生产者
 */
@RestController
@Slf4j
@RequestMapping("/api/v1/confirm")
public class ProducerController {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    // 发消息
    @GetMapping("sendMessage/{message}")
    public void sendMesaage(@PathVariable String message){
        // 设置回调
        CorrelationData correlationData = new CorrelationData("1");

        rabbitTemplate.convertAndSend(ConfirmConfig.CONFIRM_EXCHANGE_NAME,
                ConfirmConfig.CONFIRM_ROUTING_KEY,message,correlationData);

        log.info("发送消息:{}",message);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zero _s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值