RabbitMQ没有延时队列?我就教你一招,玩转延时队列

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

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<String, Object> map = new HashMap<>(16);

// 在延时交换器上指定死信交换器

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里面,我们创建了两个交换器和两个队列,但是两个队列和交换器还是有区别的,我们来看图片

RabbitMQ没有延时队列?我就教你一招,玩转延时队列

我们可以看到两个队列的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

*/

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<String, Object> map = new HashMap<>(16);

// 在延时交换器上指定死信交换器

map.put(“x-dead-letter-exchange”, DIRECT_EXCHANGE_DEAD);

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);

AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();

builder.expiration(“10000”);

AMQP.BasicProperties properties = builder.build();

channel.basicPublish(DIRECT_EXCHANGE_DELAY, DIRECT_DELAY_ROUTING_KEY, false, properties, “hello world”.getBytes());

}

总结

对于面试,一定要有良好的心态,这位小伙伴面试美团的时候没有被前面阿里的面试影响到,发挥也很正常,也就能顺利拿下美团的offer。
小编还整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家,

在这里插入图片描述

在这里插入图片描述

最后感谢大家的支持,希望小编整理的资料能够帮助到大家!也祝愿大家都能够升职加薪!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
UTING_KEY, false, properties, “hello world”.getBytes());

}

总结

对于面试,一定要有良好的心态,这位小伙伴面试美团的时候没有被前面阿里的面试影响到,发挥也很正常,也就能顺利拿下美团的offer。
小编还整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家,

[外链图片转存中…(img-RiJAjdlT-1714739973722)]

[外链图片转存中…(img-g3nArfgr-1714739973723)]

最后感谢大家的支持,希望小编整理的资料能够帮助到大家!也祝愿大家都能够升职加薪!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值