概述
電商中秒殺請求,屬於瞬間大流量,同一時刻會有大量的請求涌入到系統中,可能導致系統掛掉。應付這種瞬間大流量的其中一種方式,便是利用消息隊列。
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條。