【SpringBoot】 整合RabbitMQ 消息单独以及批量的TTL

生产者端

目录结构

导入依赖

修改yml

业务逻辑

        队列消息过期

        消息单独过期


   

        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条全部删除了。于是我猜测这个消息的存放队列就好似一个栈,虽然先生产的消息的生存时间短,但是当别的消息压在自己头上的时候是出不去的,而是必须等自己为栈顶元素才可以出栈!

猜你喜欢

转载自blog.csdn.net/m0_65563175/article/details/130463749