安装部分
为何使用延时队列
最近做微信支付的时候遇到一个问题,就是订单未支付过期取消。一开始为了简化开发速度直接用的scheduleThreadPool实现,但是后面发现如果项目部署集群的话这个定时任务会有问题,收集相关资料后就决定使用Rabbitmq的延迟队列delayed-message-exchange。
下载插件
插件下载地址:https://www.rabbitmq.com/community-plugins.html
上面有对应版本提示,按照你的rabbitmq版本下载即可
插件安装
首先把你刚才下载的插件上传至服务器,放到任意目录下(我这边放到/root目录下)
-
docker容器插件安装
如果你的rabbitmq是通过容器的方式启动的,首先进入容器docker exec -it rabbitmq /bin/bash
然后把插件拷贝进容器:
docker cp /root/rabbitmq_delayed_message_exchange-3.8.0.ez rabbitmq:plugins
此时在容器内plugins目录下执行ls命令,你会发现拷贝进来的插件:
在此目录下执行命令rabbitmq-plugins enable rabbitmq_delayed_message_exchange
使插件生效
-
正常安装
直接将插件拷贝进你的rabbitmq的plugins目录下,如果不知道你的rabbitmq安装目录的
通过whereis rabbitmq查看
使插件生效的方法同上
打开rabbitmq控制台,点击exchange,如果type里出现x-delayed-message类型,则说明安装成功
使用部分
定义队列和交换机
队列其实是一个普通队列,交换机类型是关键,设置为延迟消息类型后,消息将会在指定时间之后投递到队列中。
发送消息
/**
* @author : coderzyj
* @version : 1.0
* @description : 延时任务消息发送
*/
@Component
@Slf4j
public class DelayTaskMessageSender {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 发送消息
*
* @param message 消息体
* @param delay 延迟时间
*/
public void sendDelayMessage(DelayMessage message, Integer delay) {
log.info("发送延时任务消息:{},延迟时间:{}", JSON.toJSONString(message), delay);
rabbitTemplate.convertAndSend(RabbitConstants.Exchange.DELAY_EXCHANGE_NAME, RabbitConstants.routingKey.DELAY_ROUTING_KEY,
JSON.toJSONString(message), message1 -> {
message1.getMessageProperties().setDelay(delay);
return message1;
});
}
}
delay是延迟时间,这边是以毫秒为单位的,使用时别忘记单位转换。
消费消息
延迟队列的消费和普通消息一样,监听队列即可
@Component
@Slf4j
public class DelayMessageListener {
@RabbitListener(queues = RabbitConstants.Queue.DELAY_QUEUE_NAME)
public void handle(String message) {
log.info("接收到延时消息:message ->{}", message);
}
}
使用限制和注意事项
延迟队列插件有个很大的坑,就是不支持RAM类型的节点,关于ram和disk类型的区别不做赘述,
如果你的rabbitmq是集群的话,你必须注意有没有这类节点存在,否则将无法安装。关于这一点我吃了很大的亏。
这一点有些文章也有介绍,但是没有写明出处,我看了文档之后找到了文档原文,如下所示:
这是插件github官网 readme的最后一段话,明确了这一限制,链接:
https://github.com/rabbitmq/rabbitmq-delayed-message-exchange