既有适合小白学习的零基础资料,也有适合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)

## 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);
}

将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);
}

## 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()); }




**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化资料的朋友,可以戳这里获取](https://gitee.com/vip204888)**