RabbitMQ到底怎么实现延时队列
==================
步骤一:创建一个正常的队列,指定消息过期时间,并且指定消息过期后需要投递的死信交换器和死信交换队列。 步骤二:创建死信队列和死信交换器
RabbitMQ实现延时队列实例
================
package com.example.demo;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;
/**
@author echo @date 2021-01-14 14:35
*/
public class TopicDealProductTest {
/**
延时队列交换机
*/
private static final String DIRECT_EXCHANGE_DELAY = “dir_exchange_delay”;
/**
死信队列交换机
*/
private static final String DIRECT_EXCHANGE_DEAD = “dir_exchange_dead”;
/**
延时队列
*/
private static final String DIRECT_QUEUE_DELAY = “dir.queue.delay”;
/**
死信队列
*/
private static final String DIRECT_QUEUE_DEAD = “dir.queue.dead”;
/**
延时队列ROUTING_KEY
*/
private static final String DIRECT_DELAY_ROUTING_KEY = “delay.queue.routingKey”;
/**
延时队列ROUTING_KEY
*/
private static final String DIRECT_DEAD_ROUTING_KEY = “dead.queue.routingKey”;
private static final String IP_ADDRESS = “192.168.230.131”;
private static final int PORT = 5672;
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
Connection connection = createConnection();
// 创建一个频道
Channel channel = connection.createChannel();
sendMsg(channel);
Thread.sleep(10000);
closeConnection(connection, channel);
}
private static void sendMsg(Channel channel) throws IOException {
// 创建延时队列和延时交换器
channel.exchangeDeclare(DIRECT_EXCHANGE_DELAY, BuiltinExchangeType.DIRECT);
Map
// 在延时交换器上指定死信交换器
map.put(“x-dead-letter-exchange”, DIRECT_EXCHANGE_DEAD);
// 在延时交换器上指定死信队列的routing-key
map.put(“x-dead-letter-routing-key”, DIRECT_DEAD_ROUTING_KEY);
// 设定延时队列的延长时长 10s
map.put(“x-message-ttl”, 10000);
// 创建延时队列
channel.queueDeclare(DIRECT_QUEUE_DELAY, true, false, false, map);
// 在延时交换器上绑定延时队列
channel.queueBind(DIRECT_QUEUE_DELAY, DIRECT_EXCHANGE_DELAY, DIRECT_DELAY_ROUTING_KEY);
// 创建死信队列和死信交换器
channel.exchangeDeclare(DIRECT_EXCHANGE_DEAD, BuiltinExchangeType.TOPIC, true, false, null);
// 创建死信队列
channel.queueDeclare(DIRECT_QUEUE_DEAD, true, false, false, null);
// 在死信交换器上绑定死信队列
channel.queueBind(DIRECT_QUEUE_DEAD, DIRECT_EXCHANGE_DEAD, DIRECT_DEAD_ROUTING_KEY);
channel.basicPublish(DIRECT_EXCHANGE_DELAY, DIRECT_DELAY_ROUTING_KEY, null, “hello world”.getBytes());
}
private static void closeConnection(Connection connection, Channel channel) throws IOException, TimeoutException {
// 关闭资源
channel.close();
connection.close();
}
private static Connection createConnection() throws IOException, TimeoutException {
// 创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 设置RabbitMQ的链接参数
factory.setHost(IP_ADDRESS);
factory.setPort(PORT);
factory.setUsername(“echo”);
factory.setPassword(“123456”);
// 和RabbitMQ建立一个链接
return factory.newConnection();
}
}
到这里,其实我们不难发现,我们无非是利用了TTL这个特性,让消息在过期的时候丢弃到指定队列,死信队列其实也是一个普通队列。
执行之后,我们来看看结果,在Exchange里面,我们创建了两个交换器和两个队列,但是两个队列和交换器还是有区别的,我们来看图片
我们可以看到两个队列的Features标志是不一样的
TTL: 消息在队列中的过期时间 DLX: 该队列绑定了死信交换器 DLK: 该队列绑定的死信队列的ROUTING_KEY
在我们执行完成之后,我们可以看到,消息先被投递到了delay,该队列里面的消息,到达过期时间之后就被投递到了dead队列中去了。
那么我们上面介绍了TTL和设置AMQP.BasicProperties,这两种有一定的区别,前一个是设置队列消息过期时间,后一个是设定每条消息的过期时间。那他们的区别在哪里?
设置每条消息和设置TTL的区别
===============
其实这两种方式的区别就在于怎么判断该消息是否要被丢弃。TTL设定的队列,只要消息到达过期时间,立马就会将消息丢弃。如果是后者,可能我们队列里面有很多的消息,然后每条消息的过期时间又不一致,这个时候,如果队列出口处堵了很多没有设定过期时间的消息又不被消费的时候,队列后面的消息及时设定了过期时间也不会被丢弃,只有在设定了过期时间的消息到了队列该消费的位置,才会判定
怎么使用AMQP.BasicProperties?
=========================
package com.example.demo;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;
/**
@author echo @date 2021-01-14 14:35
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
最后,附一张自己面试前准备的脑图:
面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典
Java核心知识整理
Spring全家桶(实战系列)
Step3:刷题
既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。
以下是我私藏的面试题库:
很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。
最后祝愿各位身体健康,顺利拿到心仪的offer! jUT5eRy-1711781731313)]
Step3:刷题
既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。
以下是我私藏的面试题库:
[外链图片转存中…(img-vst1Epix-1711781731314)]
很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。
最后祝愿各位身体健康,顺利拿到心仪的offer!
参考阅读
发表评论