消息队列是一个消息存储组件,是分布式服务框架系统中的一个重要组件。用于应用间通信,消息投递后可以立即返回,消息系统确保消息的可靠性。消息使用者从消息队列获取消息后进行消费。
消息队列广泛应用在分布式服务框架中,并成为其中的必选组件。主要应用场景为应用解耦、异步处理、流量削峰等三个场景。
上下游应用如果存在RPC调用,那么下游服务异常会导致上游应用异常。因此可以将RPC直接调用改为通过消息队列进行交互,这样通过引入消息队列组件,解除了上下游应用的强耦合,可以增强整个系统的可靠性。
应用过程中有一些业务需要经过很长的处理流程才能完成业务逻辑。在串行处理过程中需要很长的处理时间,会影响系统响应时间和用户的体验。因此下游服务可以从消息队列读取后处理,这样大部分处理流程可以进行异步处理,而不会影响系统响应时间。
在一定配置和系统架构情况下,系统的处理能力总是有极限的。如果秒杀活动或者流量激增,超过系统处理上限,会导致应用崩溃。因此可以在应用前端加入消息队列,系统可以按一定频率从消息队列取出消息进行逐步处理和消费。
消息队列主要是包括生产者、消费者、消息存储、协调服务等四个部分。整体架构如下图:
主要是消息的生产方,在实际场景中生产者都是以集群形式部署,一般情况只有一个消息生产方。
主要是消息的消费方或者订阅方,会获取消息进行后续业务处理。消费者也是以集群形式部署的,一般情况下会有多个消费者进行消息消费。
消息存储主要是对消息进行持久化存储,接收生产者发送的消息,并且支持消费者对消息的消费。一般会进行多副本保存来保证消息的可靠性,避免单点故障。
主要是保存消息的存储位置和副本信息、消费者的注册和协调等。
主要是消费者消费消息时,消费者与消息存储的交换方式。
生产者发送消息失败,会自动重新投递
消费失败,会自动重新尝试再次消费
消息的消费顺序跟生产者生产顺序一致,一般可以保证分区的消息顺序性。
消息被消费之后,如果下游系统奔溃或信息丢失,就需要对已消费信息重新消费。
重试队列是指一个与原消息队列相关的一个队列,此队列用于存放消费失败的消息。
死信队列是指一个与原消息队列相关的一个队列,此队列用于存放多次消费失败的消息,此队列中的消息需要人工介入处理。
生产者有时候希望消息延迟一段时间才被消费者消费,因此有对延迟队列的需求。比如订单未支付延迟取消场景。
优先级队列:指的是消息不是按照时间顺序被消费,每个消息包含优先级信息,优先级高的消息会被优先消费。
消息队列如何设计和保证消息的持久化,影响到消息队列本身的性能特性。
消息至少被写入一次。producer如果没有收到ack,需要重试发送消息,一条消息可能写入多次
消息至多被写入一次。producer发送消息到服务端后,不论是否收到ack,都不再重试,消息可能丢失
消息确定被写入一次。producer保存发送失败消息再次发送,服务端保证重试多条消息只存储一次
当出现发生硬件故障或者软件故障时,是否会导致消息丢失或者影响消息的生产和消费。
当业务实际应用中,与评估容量有差异时,是否支持不停机状态下对消息队列进行扩缩容,已有数据是否需要进行重分配。
一个消息队列实例可以为多个租户提供服务,并且保证租户之间的数据隔离。
消息携带生存时间,在生存时间内如果没有被消费会被删除或者放入死信队列
在分布式系统中保证上下游应用执行一致
消息队列是一个常用的中间件。目前有很多常用的消息队列可供选择,本文仅仅是罗列了消息队列的一些特性,可以根据以上特性和具体业务场景来进行消息队列的选型。