SpringBoot集成RabbitMq并且实现延时队列(二)
一、插件下载
要实现延时队列,我们需要MQ提供的插件:rabbitmq_delayed_message_exchange
首先下载该插件:https://www.rabbitmq.com/community-plugins.html,也可以下载我上传的资源:资源
要注意这些版本的对应:
下载完成之后把插件copy到RabbitMQ的安装目录plugins下,进入到sbin目录下,执行以下代码:
rabbitmq-plugins.bat enable rabbitmq_delayed_message_exchange
关闭RabbitMQ服务,然后再启动(直接重启该插件可能会不生效)。
二、项目搭建
1.新建一个SpringBoot项目
application.yml配置文件如下
这里配置的是MQ的一些基本信息
spring:
# RabbitMQ 配置项,对应 RabbitProperties 配置类
rabbitmq:
host: 127.0.0.1 # RabbitMQ 服务的地址
port: 5672 # RabbitMQ 服务的端口
username: guest # RabbitMQ 服务的账号
password: guest # RabbitMQ 服务的密码
server:
port: 8889
2.新建一个消息体对象MatchDelayMessage,省略get/set方法
public class MatchDelayMessage implements Serializable {
public static final String MESSAGE_ID = "matchDelay";
public static final String EXCHANGE = "EXCHANGE-MATCH-DELAY";
public static final String QUEUE = "QUEUE-MATCH-DELAY";
public static final String ROUTING_KEY = "MATCH-DELAY";
public static final Integer DELAY = 5 * 1000;
private long currentTime;
private String roleId;
}
3.新建一个配置文件RabbitConfig
@Configuration注解表明此类是一个配置文件,这里面做的主要是队列的创建和绑定,对此有
@Configuration
public class RabbitConfig {
@Bean
public CustomExchange xDelayExchange() {
Map<String, Object> args = new HashMap<>(1);
// 这里使用直连方式的路由,如果想使用不同的路由行为,可以修改,如 topic
args.put("x-delayed-type", "direct");
return new CustomExchange(MatchDelayMessage.EXCHANGE, "x-delayed-message", true, false, args);
}
@Bean
public Queue queue() {
return new Queue(MatchDelayMessage.QUEUE, true, false, false);
}
@Bean
public Binding binding() {
return BindingBuilder.bind(queue()).to(xDelayExchange()).with(MatchDelayMessage.ROUTING_KEY).noargs();
}
}
4.新建一个消息消费者MatchDelayConsumer
@Component
@RabbitListener(queues = MatchDelayMessage.QUEUE)
public class MatchDelayConsumer {
@RabbitHandler
public void onMessage(MatchDelayMessage matchDelayMessage, Channel channel, Message message) {
System.out.println("延迟接受打印消息");
System.out.println("延迟接受打印消息的时间为:" + System.currentTimeMillis());
System.out.println("接收消息的roleId为:" + matchDelayMessage.getRoleId());
}
}
5.新建一个TestController测试发送
@RestController
@RequestMapping("test")
public class TestController {
@Autowired
private RabbitTemplate rabbitTemplate;
@RequestMapping("/mq")
public void TestRabbit() {
MatchDelayMessage message = new MatchDelayMessage();
message.setRoleId("4213");
sendDelayMessage(MatchDelayMessage.EXCHANGE, MatchDelayMessage.ROUTING_KEY, message, 5000);
}
//注意 这里的delay是毫秒,设置5秒之后被消费
public void sendDelayMessage(String exchange, String routingKey, Object mqmessage, Integer delay) {
System.out.println("发送队列消息");
System.out.println("发送队列消息的时间为:" + System.currentTimeMillis());
rabbitTemplate.convertAndSend(exchange, routingKey, mqmessage, message -> {
message.getMessageProperties().setDelay(delay);
return message;
});
}
}
启动项目,浏览器访问url:http://localhost:8889/test/mq,看控制台打印,刚好两个时间差是5秒,并且我们收到了队列里的消息roleId:4213
我只是针对简单的例子做了一个集成,如果想要深入研究的,包括MQ的几种模式,访问这位大佬的语雀文章:https://www.yuque.com/lixiaohui-t5gcl/nbabmz/fvb9ga