概述
电商中秒杀请求,属于瞬间大流量,同一时刻会有大量的请求涌入到系统中,可能导致系统挂掉。应付这种瞬间大流量的其中一种方式,便是利用消息队列。
1、利用消息队列先进先出的特性,将请求进行削峰;
2、控制好消费端的消费速度,进行必要的限流。
在消费端,要做到上面提到的第2点,在Spring Boot RabbitMQ中只需要利用
@RabbitListener注解,做一些简单配置就可以了。
一个listener对应多个consumer
默认情况一下,一个listener对应一个consumer,如果想对应多个,有两种方式。
方式一:直接在application.yml文件中配置
spring:
rabbitmq:
listener:
simple:
concurrency: 5
max-concurrency: 10
这个是个全局配置,应用里的任何队列对应的listener都至少有5个consumer,但是千万别这么做,因为一般情况下,一个listener对应一个consumer是够用的。只是针对部分场景,才需要一对多。
方式二:直接在@RabbitListener上配置
@Component
public class SpringBootMsqConsumer {
@RabbitListener(queues = "spring-boot-direct-queue",concurrency = "5-10")
public void receive(Message message) {
System.out.println("receive message:" + new String(message.getBody()));
}
}
利用@RabbitListener中的concurrency属性进行指定就行。例如上面的
concurrency = “5-10”
就表示最小5个,最大10个consumer。启动消费端应用后,找到spring-boot-direct-queue这个队列的consumer,会发现有5个。
这5个消费者都可以从spring-boot-direct-queue这个队列中获取消息,加快队列中消息的消费速度,提高吞吐量。
限流
我们经过压测,来判断consumer的消费能力,如果单位时间内,consumer到达的消息太多,也可能把消费者压垮。
得到压测数据后,可以在@RabbitListener中配置prefetch count。
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class SpringBootMsqConsumer {
@RabbitListener(queues = "spring-boot-direct-queue",concurrency = "5-10",containerFactory = "mqConsumerlistenerContainer")
public void receive(Message message) {
System.out.println("receive message:" + new String(message.getBody()));
}
}
只需要在@RabbitListener中,用containerFactory指定一个监听器工厂类就行。这里用的是:
containerFactory = “mqConsumerlistenerContainer”
定义监听器工厂类很简单。
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMqConfig {
@Autowired
private CachingConnectionFactory connectionFactory;
@Bean(name = "mqConsumerlistenerContainer")
public SimpleRabbitListenerContainerFactory mqConsumerlistenerContainer(){
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setPrefetchCount(50);
return factory;
}
}
上面有一句factory.setPrefetchCount(50);,就是用于设置prefetch count的,启动后,会在spring-boot-direct-queue队列的consumer中体现出来。
配置成功后,consumer单位时间内接收到消息就是50条。