一、增加处理能力
优化系统架构、增加服务器资源、采用负载均衡等手段,以提高系统的处理能力和并发处理能力。通过增加服务器数量或者优化代码,确保系统能够及时处理所有的消息。
二、异步处理
将消息的处理过程设计为异步执行,即接收到消息立即返回响应,然后将消息放入队列中进行后续处理。这样可以避免同步请求的阻塞,提高系统的吞吐量和响应速度。
三、消息分片
如果消息体较大或者复杂,可以考虑将消息分片处理。将消息拆分为多个小的部分进行处理,减少单个消息的处理时间,从而提高整体处理能力。
四、集群扩展
根据实际情况,可以考虑通过添加更多的节点来扩展消息处理的集群规模,实现分布式部署和负载均衡,以应对大量消息的处理需求。
五、优化数据库操作
如果消息的处理涉及到数据库操作,可以考虑对数据库查询和写入进行性能优化,如建立索引、合理使用缓存等,以减少数据库的压力。
六、监控和报警
建立监控系统,实时监测消息队列的积压情况、处理延迟等指标,并设置相应的报警机制,及时发现和解决潜在问题,确保消息的正常处理。需要根据具体的场景和需求来选择适合的解决方案,综合考虑各种因素,以提高系统的消息处理能力和性能。
七、增加消费者数量
增加消费者可以提高消息处理速度,从而减少消息积压。可以根据消息的类型和优先级分配消费者,使消息得到及时处理。
八、增加队列
可以增加队列数量来缓解消息积压。根据消息的类型和优先级,可以将不同类型的消息存储在不同的队列中,更好的管理消息流量
九、设置消息的过期时间
可以设置消息的过期时间,当消息在队列中等待时间超过指定时间时,会被自动删除,直到消息被正确处理或超过最大重试次数为止。
十、使用限流机制
可以使用限流机制来控制消费者的消费速度,避免消息过多导致消费者无法及时处理。可以使用Qos机制,设置每个消费者同时处理消息的最大数量,从而保证系统的性能和稳定性。
如何进行限流了
电商中秒杀请求,属于瞬间大流量,同一时刻会有大量的请求涌入到系统中,可能导致系统挂掉。应付这种瞬间大流量的其中一种方式,便是利用消息队列。
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条。