rabbitMQ的高级特性

 

 


 

 

目录

  • rabbitMQ的高级特性
  • 1. 限制消费者每秒从队列拉取的消息的数量
  • 2. 设置队列/消息的过期时间
  • 3. 死信交换机
  • 4. 延迟队列

 

使用这些特性解决一些特定的问题

1. 限制消费者每秒从队列拉取的消息的数量

如果并发数量很高,那么这个时候队列中就会有很多消息等待处理,如果不限制消费者的拉取数量,消费者就会每秒拉取很多的消息,最后还是会达到一个很高的并发数,消费者服务器照样存在崩溃的可能性。

使用前提:消费者采用的是手动确认模式

修改配置文件,这里使用的是yml格式

spring:
  rabbitmq:
    listener:
      simple:
        acknowledge-mode: manual
        prefetch: 1000 # 这个数量需要根据机器性能自己进行调节,这里只是一个演示

2. 设置队列/消息的过期时间

给队列设置过期时间

队列的过期时间并不是说到达了时间这个队列被删除。
设置队列的过期时间是指:
	给队列中的每一个消息都设置一个过期时间,从消息进入该队列开始计算时间,
	如果消息还未被消费就过期,那么该消息将不会获得被消费的机会。
		但并不是直接删除该消息,而且该消息到达队首的时候进行删除,该消息不会被消费
	如果给消息单独设置了过期时间,那么队列的过期时间不会生效

给队列设置过期,在创建队列的时候就可以进行指定过期了

代码:

@Bean("queue1")
public Queue buildQueue1() {
	// ttl 中的过期时间单位是 ms(毫秒)
    return QueueBuilder.durable(queue1).ttl(3000).build();
}

除了使用 ttl() 之外,还可以这样,ttl其实就是调用了这个方法

@Bean("queue1")
public Queue buildQueue1() {
	return QueueBuilder.durable(queue1)
	.withArgument("x-message-ttl", 3000) // ttl其实就是调用了这个方法
	.build();
}


给消息设置过期时间:

在给发送消息时 创建一个消息发送处理器(MessagePostProcessor)进行设置,不推荐和队列过期时间一起设置

代码: 这里使用的是springboot的测试方法

@Autowired
private RabbitTemplate rabbitTemplate;

@Test
void contextLoads() {
    Map<String, Object> message = new HashMap<>();
    message.put("product_id", 10);
    message.put("num", 50);
    message.put("price", 600);

    MessagePostProcessor messagePostProcessor = message1 -> {
        message1.getMessageProperties().setExpiration("3000");
        return message1;
    };
    /*
    * String exchange 交换机名称
    * String routingKey 路由key
    * final Object object 要发送的消息
    * MessagePostProcessor messagePostProcessor 消息发送处理器
    */
    for (int i = 0; i < 10000; i++) {
        rabbitTemplate.convertAndSend(MyConfig.exchange
                , "lazy.orange.abc"
                , JSON.toJSONString(message), messagePostProcessor);
    }
}

 

3. 死信交换机

死信交换机简单来说就是:“死掉”的消息使用的一个交换机
死信交换机英文为 Dead Letter Exchange(DLX)

消息成为死信的三种情况:
	1. 队列消息长度达到了最大长度的限制
	2. 消费者没有确认消息,并且不允许消息重新发送
	3. 消息超时未被消费

死信交换机图示:

amqpTemplate 如何获取rabbitmq队列堆积数量 rabbitmq 队列数量上限_spring

当消息队列中的消息成为死信的时候,消息会被发送到死信交换机。
死信交换机和正常的交换机是一样的,只是用来处理死信的交换机。
死信交换机和普通交换机并没有什么本质的不同。
在使用死信交换机的时候,死信队列就成为了死信交换机的消费者。


在新建队列的时候指定死信交换机:
这里只写出 核心代码

// 死信交换机的名称
public static String exchange_name02="dead-exchange"; 

/**
 * 创建死信交换机,和创建普通交换机的方式一样
 * @return
 */
@Bean(value = "deadExchange")
public Exchange buildDeadExchange(){
    return ExchangeBuilder.topicExchange(exchange_name02).build();
}

/**
 * 创建队列,并且绑定死信交换机,
 * 给死信交换机发消息的时候,发消息的队列充当死信交换机的生产者
 * @return
 */
@Bean("queue01")
public Queue buildQueue01(){
    //withArgument("x-message-ttl",10000):设置队列的过期时间
    return QueueBuilder.durable(queue_name01).
    		// 设置队列超时时间 30s
            withArgument("x-message-ttl",30000)
            //设置队列的最大容量
            .withArgument("x-max-length",10)
            //队列与死信交换机绑定
            .withArgument("x-dead-letter-exchange",exchange_name02)
            //队列发送消息时需要绑定的routing-key
            .withArgument("x-dead-letter-routing-key","abc")
            .build();
}

/**
 * 队列02和死信交换机进行绑定
 */
@Bean
public Binding binding02(Queue queue02,Exchange deadExchange){
    return BindingBuilder.bind(queue02).to(deadExchange).with("abc").noargs();
}

在创建队列时限制队列长度的方法:

@Bean("queue01")
public Queue buildQueue01(){
    return QueueBuilder.durable(queue_name01).
            //设置队列的最大容量
            .withArgument("x-max-length",10)
            .build();
}

4. 延迟队列

也就是消息进入队列之后不会被立即进行消费,只有在到达了指定时间后,这个消息才会被消费。

但是在RabbitMQ 中并没有提供延迟队列,但是可以通过: 消息的过期时间 + 死信队列 的方式实现延迟效果

实现思路:
	1. 给需要延迟的消息设置过期时间,然后发送到队列中(队列一)
	2. 给该队列(队列一)绑定一个死信交换机
	3. 死信交换机将消息转发道对应的队列中(队列二)
	4. 让消费者监听存放延迟死信的队列(队列二)
  • 1图解:

amqpTemplate 如何获取rabbitmq队列堆积数量 rabbitmq 队列数量上限_发送消息_02