RabbitMQ消息单独与批量的TTL详细介绍
作者:小白的救赎
TTL(Time To Live)存活时间。表示当消息由生产端存入MQ当中的存活时间,当时间到达的时候还未被消息就会被自动清除。RabbitMQ可以对消息单独设置过期时间也可以对整个队列(并不是队列,而是队列中的消息)设置过期时间。
生产者端
目录结构
导入依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> <version>2.5.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies>
修改yml
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
#三个类型:none默认不开启确认回调 correlated开启确认回调
#simple也会确认回调 还会调用waitForConfirms()方法或waitForConfirmsOrDie()方法
publisher-confirm-type: correlated # 开启确认回调
publisher-returns: true # 开启退回回调
业务逻辑
队列消息过期
第一段代码即是定义交换机与队列的名称并使其进行绑定,仅是一个配置类的效果。第二段代码就是生产者产生消息的方法,只需要在意for循环里面的逻辑即可。而图1即是创建出来的队列以及生产的10条消息,在10s会自动删除。因为在配置类中已经定义了TTL。
/** * 定义交换机与队列的Bean 并且使之绑定 */ @Component public class RabbitMQConfig { public static final String TTL_EXCHANGE_NAME = "ttl_exchange_name"; public static final String TTL_QUEUE_NAME = "ttl_queue_name"; @Bean("ttlExchange") public Exchange ttlExchange(){ return ExchangeBuilder.topicExchange(TTL_EXCHANGE_NAME).durable(true).build(); } //配置队列的时候顺带上ttl()方法 其内部对MQ设置了参数"x-message-ttl" //注意这里的单位是毫秒 所以我写的参数为10000毫秒即10秒 @Bean("ttlQueue") public Queue ttlQueue(){ return QueueBuilder.durable(TTL_QUEUE_NAME).ttl(10000).build(); } @Bean public Binding ttl(@Qualifier("ttlExchange") Exchange exchange, @Qualifier("ttlQueue") Queue queue){ return BindingBuilder.bind(queue).to(exchange).with("test.#").noargs(); } }
@SpringBootTest @RunWith(SpringRunner.class) class RabbitmqProducerApplicationTests { @Autowired private RabbitTemplate rabbitTemplate; @Test void testTTL(){ rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() { @Override public void confirm(CorrelationData correlationData, boolean b, String s) { if(b) System.out.println("交换机成功接受到了消息"); else System.out.println("消息失败原因" + s); } }); rabbitTemplate.setMandatory(true); rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() { @Override public void returnedMessage(Message message, int i, String s, String s1, String s2) { System.out.println("队列接受不到交换机的消息进行了失败回调"); } }); // 以上代码只是保证消息传递的可靠性 与TTL无关 for(int i = 0; i < 10; ++i){ rabbitTemplate.convertAndSend(RabbitMQConfig.TTL_EXCHANGE_NAME,"test.heHe","HelloWorld"); } } }
图1
消息单独过期
这里的配置类还是如上相同:队列中的消息10s自动过期,再对其中一条消息进行处理就可以更好的明白这两种过期的区别:其中一条消息设置了5s自动过期,通过图2可以发现队列中有11条消息,当5s后变为10条消息,再过了5s后就没有消息。
@SpringBootTest @RunWith(SpringRunner.class) class RabbitmqProducerApplicationTests { @Autowired private RabbitTemplate rabbitTemplate; @Test void testTTL(){ rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() { @Override public void confirm(CorrelationData correlationData, boolean b, String s) { if(b) System.out.println("交换机成功接受到了消息"); else System.out.println("消息失败原因" + s); } }); rabbitTemplate.setMandatory(true); rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() { @Override public void returnedMessage(Message message, int i, String s, String s1, String s2) { System.out.println("队列接受不到交换机的消息进行了失败回调"); } }); // 以上代码只是保证消息传递的可靠性 与TTL无关 // 消息的后处理对象 设置一些消息的参数信息 MessagePostProcessor messagePostProcessor = new MessagePostProcessor(){ @Override public Message postProcessMessage(Message message) throws AmqpException { message.getMessageProperties().setExpiration("5000");//设置消息对象5s后过期 return message; } }; //消息单独5s过期 rabbitTemplate.convertAndSend(RabbitMQConfig.TTL_EXCHANGE_NAME,"test.heHe","HelloWorld",messagePostProcessor); //队列中的消息全体10s过期 for(int i = 0; i < 10; ++i){ rabbitTemplate.convertAndSend(RabbitMQConfig.TTL_EXCHANGE_NAME,"test.heHe","HelloWorld"); } } }
图2
到这真的就以为结束了吗,当我把for循环的10条消息放到单独过期的消息上面,发现了新大陆:一开始的消息也是如图2所示为11条,但是但是,过了5s后并不会消除一条消息,而是过了10s后将11条全部删除了。于是我猜测这个消息的存放队列就好似一个栈,虽然先生产的消息的生存时间短,但是当别的消息压在自己头上的时候是出不去的,而是必须等自己为栈顶元素才可以出栈!
到此这篇关于RabbitMQ消息单独与批量的TTL详细介绍的文章就介绍到这了,更多相关RabbitMQ消息的TTL内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!