提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
已完成docker形式部署rabbitMQ容器后,在次基础上新增延迟队列需求
一、部署方面
1.1、查询rabbitMQ版本
代码如下(示例):
# 格式
docker inspect rabbitmq:[版本]
# 例
docker inspect rabbitmq:management
根据rabbitMQ版本,在官网提供地址中,查询并下载指定版本的延迟插件
1.2、下载指定版本延迟插件
1.3、配置容器
3.1、拷贝文件
使用docker cp 指令,讲主机内文件拷贝到指定容器中的指定目录中,延迟插件需要存放在/plugin目录下
# 格式
docker cp 主机文件目录地址 [容器id]:/plugins
# 例
docker cp /rabbitmq_delayed_message_exchange-3.9.0.ez 容器id:/plugins
3.2、进入容器后操作
# 进入容器
docker exec -it 容器id bash
# 检查插件是否存在
cd plugins
ls |grep delay
# 启用插件(注意在 /plugins 目录中)
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
# 退出容器,并重启容器
exit
docker restart 容器id
3.2、检查结果
二、Java代码实现
1、配置文件
@Configuration
public class RabbitConfig {
public static final String EXCHANGE_NAME = "delay_exchange"; //延迟交换机
public static final String EXCHANGE_TYPE = "x-delayed-message"; //交换机类型,采用延迟方式
public static final String QUEUE_NAME = "delay_queue"; //延迟队列名称
/*
* 声明延迟交换机
*/
@Bean
CustomExchange customExchange() {
Map<String, Object> args = new HashMap<>();
args.put("x-delayed-type", "direct");
return new CustomExchange(EXCHANGE_NAME, EXCHANGE_TYPE, true, false,args);
}
/*
* 声明延迟队列
*/
@Bean
Queue queue() {
return new Queue(QUEUE_NAME, true, false, false);
}
/*
* 交换机和队列之间绑定
*/
@Bean
Binding binding() {
return BindingBuilder.bind(queue())
.to(customExchange()).with(QUEUE_NAME).noargs();
}
}
2、生产者
/**
* 发送信息
*
* @param exchange 延迟交换机
* @param routingKey 路由键
* @param obj 消息体
* @param delayTime 延迟时间(单位为ms)
*/
public void teacherStartRollCall(Map<String, String> callInfoMap,Integer delaySchedule) {
//消息的处理
Message message = MessageBuilder.withBody(JSON.toJSONString(callInfoMap).getBytes(StandardCharsets.UTF_8))
.setContentType(MessageProperties.CONTENT_TYPE_JSON)
.setContentEncoding("utf-8")
.setMessageId(UUID.randomUUID().toString())
.setTimestamp(new Date())
.build();
/*
* @param exchange 交换机名称
* @param routingKey 路由键
* @param obj 消息体
* @param delayTime 延迟时间(单位为ms)
*/
rabbitTemplate.convertAndSend("delay_exchange,"x-delayed-message", message, delayTime -> {
delayTime.getMessageProperties().setDelay(delaySchedule);
return delayTime;
});
}
3、消费者
@Component
@RabbitListener(queues = "delay_queue") //监听的队列
public class RollCallConsumer {
@Autowired
CallTempService callTempService;
@RabbitHandler(isDefault = true)
public void process(Message message, Channel channel) throws Exception {
System.out.println("----------监听学生提交队列,开始处理----------");
try {
// 消费生产者发送的消息
String msgBody = new String(message.getBody(), StandardCharsets.UTF_8);
// 业务涉及到的消息转换(注意)
Map<String, String> callInfoMap = JSONObject.parseObject(msgBody, new TypeReference<Map<String, String>>() {
});
//消息进行回复,正常消费
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (Exception e) {
channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
System.err.println("======发生异常,消费产生错误,拒收消息======");
throw e;
}
}
}