RabbitMQ发布确认高级版,头条大数据开发面试算法

27 阅读5分钟

img img img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat; import java.util.Date;

/** * @Description: 发布确认高级版生产者 * @Author: hong * @Date: 2024-03-05 20:58 * @Version: 1.0 **/ @Slf4j @RequestMapping("/confirm/") @RestController public class ConfirmProducerController { @Autowired private RabbitTemplate rabbitTemplate;

//http://localhost:8080/confirm/sendMsg/Hi,JAVA小生不才
@GetMapping("sendMsg/{message}")
public void sendMsg(@PathVariable String message) {
    log.info("当前时间:{},发送信息给队列:{}",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) , message);
    rabbitTemplate.convertAndSend(ConfirmConfig.CONFIRM\_EXCHANGE\_NAME, ConfirmConfig.CONFIRM\_ROUTING\_KEY, message);
}

}


## 5.消费者



package com.hong.springboot.rabbitmq.consumer;

import com.hong.springboot.rabbitmq.config.ConfirmConfig; import com.hong.springboot.rabbitmq.config.DelayedQueueConfig; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat; import java.util.Date;

/** * @Description: 发布确认高级版消费者 * @Author: hong * @Date: 2024-03-05 21:05 * @Version: 1.0 **/ @Slf4j @Component public class ConfirmConsumer { @RabbitListener(queues = ConfirmConfig.CONFIRM_QUEUE_NAME) public void receiveConfirmMessage(Message message){ String msg = new String(message.getBody()); log.info("当前时间:{},收到信息{}",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) , msg); } }


正常情况下,发送[http://localhost:8080/confirm/sendMsg/Hi,JAVA小生不才](//http://localhost:8080/confirm/sendMsg/Hi,JAVA%E5%B0%8F%E7%94%9F%E4%B8%8D%E6%89%8D)  
 ![在这里插入图片描述](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/f0a166ca91cd4502a3389df870d5546f~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771322308&x-signature=mt72P1rLM3%2BYdcwf0uiZ7H5ok8M%3D)


## 6.回调接口



package com.hong.springboot.rabbitmq.config;

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.stereotype.Component;

import javax.annotation.PostConstruct;

/** * @Description: 发布确认高级版消息生产者的回调接口 * @Author: hong * @Date: 2024-03-09 21:58 * @Version: 1.0 **/ @Slf4j @Component public class MyCallBack implements RabbitTemplate.ConfirmCallback{ @Autowired private RabbitTemplate rabbitTemplate;

@PostConstruct
public void init(){
    rabbitTemplate.setConfirmCallback(this);
}

/\*\*

* 交换机不管是否收到消息的一个回调方法 * 1.收到消息 * correlationData 保存回调消息的id及相关信息 * b true 交换机收到消息 * s null * 2.未收到消息 * correlationData 保存回调消息的id及相关信息 * b false 交换机未收到消息 * s 失败的原因 * @param correlationData 消息相关数据 * @param b 交换机是否收到消息 * @param s 没收到消息的原因 */ @Override public void confirm(CorrelationData correlationData, boolean b, String s) { String id = correlationData != null ? correlationData.getId() : ""; if (b) { log.info("交换机已经收到id为:{}的消息", id); } else { log.info("交换机还未收到id为:{}消息,原因:{}", id, s); } } }


修改ConfirmProducerController中sendMsg方法  
 交换机改个名字模拟交换机收不到消息



@GetMapping("sendMsg/{message}")
public void sendMsg(@PathVariable String message) {
    CorrelationData correlationData = new CorrelationData("1");
    log.info("当前时间:{},发送信息给队列:{}",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) , message);
    rabbitTemplate.convertAndSend(ConfirmConfig.CONFIRM\_EXCHANGE\_NAME+"123", ConfirmConfig.CONFIRM\_ROUTING\_KEY, message,correlationData);
}

![在这里插入图片描述](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/677a168f6ebe4a0691d79bf30b743241~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771322308&x-signature=5F8jM7RoHUwRuhMgUqXkr8%2FEyf4%3D)  
 将routingKey改个名字模拟队列收不到消息



@GetMapping("sendMsg/{message}")
public void sendMsg(@PathVariable String message) {
    CorrelationData correlationData1 = new CorrelationData("1");
    log.info("当前时间:{},发送信息给队列:{}",
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) , message+"----"+ConfirmConfig.CONFIRM\_ROUTING\_KEY);
    rabbitTemplate.convertAndSend(ConfirmConfig.CONFIRM\_EXCHANGE\_NAME, ConfirmConfig.CONFIRM\_ROUTING\_KEY,
            message+"----"+ConfirmConfig.CONFIRM\_ROUTING\_KEY,correlationData1);

    CorrelationData correlationData2 = new CorrelationData("2");
    log.info("当前时间:{},发送信息给队列:{}",
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) , message+"----"+ConfirmConfig.CONFIRM\_ROUTING\_KEY+"abc");
    rabbitTemplate.convertAndSend(ConfirmConfig.CONFIRM\_EXCHANGE\_NAME, ConfirmConfig.CONFIRM\_ROUTING\_KEY+"abc",
            message+"----"+ConfirmConfig.CONFIRM\_ROUTING\_KEY+"abc",correlationData2);
}

![在这里插入图片描述](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/f9c8bdf3db0f4dcd8293920c61ee07c5~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771322308&x-signature=gvLUU51bKaDsjBDg%2Bx%2Fqdh7ybMw%3D)


## 7.回退消息


从以上模拟场景可以看出,在仅开启生产者确认机制,交换机接收到消息后,会直接给生产者发送确认消息,但若发现该消息不可路由,那么消息会被直接丢弃,此时生产者是不知道消息被丢弃的。因此我们借用**mandatory参数**在当消息传递过程中不可达目的地时将消息返回给生产者。


### 7.1.开启消息回退机制


配置文件中添加如下配置



#开启消息回退机制 spring.rabbitmq.publisher-returns=true


### 7.2. 添加消息回退回调



@PostConstruct
public void init(){
    rabbitTemplate.setConfirmCallback(this);
    rabbitTemplate.setReturnsCallback(this);
}

/\*\*

* 当消息传递过程中不可达目的地时将消息返回给生产者 * 只有不可达目的地时才回调 * @param returnedMessage */ @Override public void returnedMessage(ReturnedMessage returnedMessage) { log.error("消息:{},被交换机 {} 退回,原因:{},路由key:{},code:{}", new String(returnedMessage.getMessage().getBody()), returnedMessage.getExchange(), returnedMessage.getReplyText(), returnedMessage.getRoutingKey(), returnedMessage.getReplyCode()); }


![在这里插入图片描述](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/f2fc5eb3c0a64734bd80807f418be0b1~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771322308&x-signature=xMj6BWKmJ9b5pF9X8SGfcUEWpzA%3D)








![img](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/8b52f617c9b44997bec13b4011741fc6~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771322308&x-signature=0Q9%2BNxgdfTuWq5qDvCTQnb6Xg2w%3D)
![img](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/650a74e2bc2148ec8b4b6fad67d7da11~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771322308&x-signature=bFftGizc7meQ4nWlFv065%2FmUR8Q%3D)
![img](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/aa31e727a26445c48e5677a0280b6477~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771322308&x-signature=5pzsoub5mvFOQJyLG%2FIsGhP%2Fte8%3D)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**


**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化资料的朋友,可以戳这里获取](https://gitee.com/vip204888)**