RabbitMQ利用延迟插件实现延时队列
摘要:本文使用docker部署rabbitmq,利用插件,使用SpringBoot来整合rabbitmq简单实现延时队列
docker部署rabbitmq
docker安装步骤略
本文使用rabbitmq:3.9.1版本
部署rabbimq
1.拉取镜像
docker pull rabbitmq:3.9.1
2.启动容器
docker run -e RABBITMQ_DEFAULT_USER=root -e RABBITMQ_DEFAULT_PASS=123456 --name mq --hostname mq1 -p 15672:15672 -p 5672:5672 -d rabbitmq:3.9.1
-e:设置参数配置(初始用户登录账号密码)
-p:端口映射
3.进入rabbitmq容器开启web访问插件
docker exec -it mq /bin/bash
进入容器后执行命令开启插件
rabbitmq-plugins enable rabbitmq_management
至此docker部署rabbitmq完毕,可访问xx.xx.xx.xx:15672来访问
下载添加延迟插件
本文使用3.9.1版本rabbitmq,提供相应插件(3.9.x都可使用)
下载地址
链接:https://pan.baidu.com/s/1O1CbgsmkAIlUYBHkE_6PDw?pwd=ut5z
提取码:ut5z
下载完成后需将文件传入容器
1.传入文件(文件存放路径按实际情况修改)
docker cp /root/rabbitmq_delayed_message_exchange-3.9.0.ez 3f3bf8b3b359:/plugins
2.进入容器
docker exec -it mq /bin/bash
3.开启插件
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
4.重启容器
docker restart mp
进入rabbitmq的web管理页面查看是否生效
新建交换机时,type中出现该选项就代表生效
SpringBoot整合Rabbitmq使用延时队列
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
添加配置文件信息
spring:
rabbitmq:
host: xx.xx.xx.xx
port: 5672
username: root
password: 123456
编写rabbitmq配置文件初始化交换机,队列以及队列和交换机的绑定
package com.syb.springboottestdemo.config;
import com.syb.springboottestdemo.constant.RabbitConstant;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.CustomExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* @Author: syb
* @Description: rabbitmq配置类
* @DateTime: 2022/8/1 11:08
* @Params:
* @Return
*/
@Configuration
public class RabbitConfig {
/**
* 延时队列交换机
*
* @return
*/
@Bean
public CustomExchange delayExchange() {
Map<String, Object> args = new HashMap<>();
args.put("x-delayed-type", "direct");
return new CustomExchange(RabbitConstant.DELAY_EXCHANGE, "x-delayed-message", true, false, args);
}
/**
* 延时队列
*
* @return
*/
@Bean
public Queue delayQueue() {
return new Queue(RabbitConstant.DELAY_QUEUE, true);
}
/**
* 给延时队列绑定交换机
*
* @return
*/
@Bean
public Binding delayBinding(Queue delayQueue, CustomExchange delayExchange) {
return BindingBuilder.bind(delayQueue).to(delayExchange).with(RabbitConstant.DELAY_KEY).noargs();
}
}
常量类
package com.syb.springboottestdemo.constant;
public class RabbitConstant {
/**
* 交换机
*/
public static final String DELAY_EXCHANGE = "delay_exchange";
/**
* 队列
*/
public static final String DELAY_QUEUE = "delay_queue";
/**
* 路由
*/
public static final String DELAY_KEY = "delay_key";
}
生产者
package com.syb.springboottestdemo.listener;
import com.syb.springboottestdemo.constant.RabbitConstant;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class RabbitProducer {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 发送消息
*
* @param object 发送对象
* @param millisecond 延时(毫秒)
*/
public void sendDelayMessage(String object, long millisecond) {
this.rabbitTemplate.convertAndSend(
RabbitConstant.DELAY_EXCHANGE,
RabbitConstant.DELAY_KEY,
object,
message -> {
message.getMessageProperties().setHeader("x-delay", millisecond);
return message;
}
);
}
}
消费者
package com.syb.springboottestdemo.listener;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.Channel;
import com.syb.springboottestdemo.constant.RabbitConstant;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class RabbitConsumer {
/**
* 接收消息
*
* @param object 监听的内容
*/
@RabbitListener(queues = RabbitConstant.DELAY_QUEUE)
public void cfgUserReceiveDealy(String object, Message message, Channel channel) throws IOException {
ObjectMapper mapper=new ObjectMapper();
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
try {
System.out.println(object);
} catch (Exception e) {
System.out.println(e);
/**
* basicRecover方法是进行补发操作,
* 其中的参数如果为true是把消息退回到queue但是有可能被其它的consumer(集群)接收到,
* 设置为false是只补发给当前的consumer
*/
channel.basicRecover(false);
}
}
}
测试一下
package com.syb.springboottestdemo.controller;
import com.syb.springboottestdemo.listener.RabbitProducer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class RabbitDelayController {
@Autowired
RabbitProducer rabbitProducer;
@GetMapping(value = "/sendRabbitMqMessage")
public void sendDelayMessageTest(){
Map<String,String> map=new HashMap<>();
map.put("第一条信息","信息一");
map.put("第二条信息","信息二");
rabbitProducer.sendDelayMessage(map.get("第一条信息"),5000);
rabbitProducer.sendDelayMessage(map.get("第二条信息"),10000);
}
}
简单测试接口后五秒和十秒时消费者会消费信息,成功实现延时操作
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程