消息队列英文为
Message Queue
(MQ
),是应用程序和应用程序之间的通信方法,本文介绍相关概念。
生产者、消费者模式
说到消息队列,绕不开生产者消费者模式。
消息驱动的系统分为消息队列、消息生产者、消息消费者,生产者负责产生消息,消费者负责对消息进行处理。
生产者是一系列生产商品的线程,生产消费者所需的数据;消费者是可以处理数据的一些列线程。
二者靠一个队列交互,生产者生产数据放到队列中,消费者从队列中提取数据进行处理;
消费者可以是下级消费者的生产者,仅需在中间再添加一个队列即可;
这个队列,称作消息队列。
消息
消息是软件对象之间交互和通讯的数据,消息可以是简单的文本字符串也可以是复杂的对象。
消息作为消息队列中最基本的概念,本质上是一段数据,能被一个或多个应用程序所理解,是应用程序之间传递信息的载体。
在消息队列中,把应用程序交由消息队列传输的数据定义为消息,可以定义消息的内容并对消息进行广义的理解。
消息队列
消息队列英文为 Message Queue
(MQ
),是应用程序和应用程序之间的通信方法。 我们可以把消息队列比作是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用。
简单来说,消息队列是指利用高效可靠的消息传输机制及运行平台无关的数据交流,并基于数据通信来进行分布式系统的集成,可以在分布式环境下提供应用解耦、弹性伸缩、冗余存储、流量削峰、异步通信、数据同步等功能,其作为分布式系统架构中的一个重要组件,有着举足轻重的地位。
消息队列是一种异步的服务将通信方式,适用于无服务器和微服务架构,消息在被处理和删除之前一直存储在队列上。每条消息仅可被一位用户处理一次。消息队列可被用于分离重量级处理、缓冲或批处理工作以及解耦高峰期工作负荷。
示例
在不使用消息队列的时候,用户请求的数据将会直接写入数据库,在高并发情况下数据库压力倍增,响应速度变慢。使用消息队列之后,用户请求数据发送给消息队列后立即返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。由于消息队列服务器处理速度快于数据库,因此响应速度得到大幅改善。
通过异步处理将短时间高并发产生的事务消息存储在消息队列中从而削平高峰期的并发事务。
优势
在项目中,可将一些无需即时返回且耗时的操作提取出来,进行异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。
- 异步提速消息队列是异步单向的消息,发送消息被设计成无需等待处理的完成。任务异步处理,将不需要同步处理的,且耗时较长的操作,由消息队列通知消息接收方进行异步处理。提高了应用程序的响应速度。
- 应用解耦应用程序解耦合,MQ 充当中介,生产方通过 MQ 与消费方交互,将应用程序进行解耦。
- 削峰填谷消息队列把请求的压力保存一下然后逐渐释放出来,按照自己的节奏来处理。在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见;如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用MQ能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
- 可恢复性系统的一部分组件失效时,不会影响到整个系统。MQ降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
- 排序保证消息队列可以控制数据处理的顺序,因为消息队列本身使用的是队列这个数据结构, FIFO (先进先出),在一些场景数据处理的顺序很重要,比如商品下单顺序等。
特性
- 业务无关一个具有普适性质的消息队列组件不需要考虑上层的业务模型,只做好消息的分发就可以了,上层业务的不同模块反而需要依赖消息队列所定义的规范进行通信。
- FIFO 先进先出先投递先到达是消息队列和
buffer
的本质区别 - 容灾对于普适的消息队列组件而言,节点的动态删减和消息的持久化都是支持容灾能力的重要基本特性。
- 性能消息队列的吞吐量上去了整个系统的内部通信效率也会有提高
缺点
- 系统可用性降低在加入MQ之前,你不用考虑消息丢失或者说MQ挂掉等等的情况,但是,引入MQ之后你就需要去考虑了。
- 系统复杂性增加加入MQ之后,你需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题。
- 数据一致性问题带来了数据丢失、结果重复、内存爆炸等问题。
传输模式
消息队列的传输模式可以分为两种,分别是点对点模式(point to point,queue
)和发布/订阅模式(publish/subscribe,topic
)
点对点模式
点对点模型用于消息生产者和消息消费者之间点到点的通信,消息生产者将消息发送到由某个名字标识的特定消费者,这个名字实际上对应消费服务中的一个队列,在消息传递给消费者之前它被存储在这个队列中,队列消息可以存放在内存也可以持久化,以保证在消息服务出现故障时仍然能够传递消息。
消息生产者向一个特定的队列发送消息,消息消费者从该队列中接收消息,消息生产者和消费者可以不同时处于运行状态,每一个成功处理的消息都是由消息消费者签收确认(Acknowledge
,ACK
)。
点对点模式下包含三个角色:消息队列、发送者(生产者)、接收者(消费者)
消息发送者生产消息并发送到消息队列中,然后消息接收者从队列中取出并消费。消息被消费后队列中不再有存储,所以消息接收者不可能消费到已经被消费的消息。
点对点模式的特点在于每个消息只有一个接收者(消费者),也就是说消息一旦被消费就不会在消息队列中存在。另外,发送者和接收者之间是没有依赖性的,发送者发送消息之后,不管有没有接收者在运行,都不会影响到发送者下次发送消息。再者,接收者在成功接收消息之后需向队列应答成功,以便消息队列删除当前接收的消息。
传统的点对点消息中间件通常是由消息队列服务、消息传递服务、消息队列、消息应用程序接口API组成。
其特点在于每个消息只用一个消费者,发送者和接收者之间没有时间依赖,接收者确认消息接收和处理成功。
发布/订阅模式
发布/订阅(pub/sub
)模式中包含三个角色:角色主题(topic
)、发布者(publisher
)、订阅者(subscriber
)
发布/订阅模型支持先一个特定的消息主题生产消息,零个或多个订阅者可能对接收来自特定消息主题的消息感兴趣。这种模型下,发布者和订阅者彼此不知道对象,就好比是匿名公告板。
发布/订阅模式可以被概况为多个消费者可以获得消息,在发布者和订阅者之间存在时间依赖性。发布者需要建立一个订阅(subscription
)以便能够被消费者订阅,订阅者必须保证持续的活动状态并接收消息。
发布订阅消息模型中,支持向一个特定的主题发布消息,零个或多个订阅者接收来自这个消息主题的消息。在这种模型下,发布者和订阅者彼此不知道对象。发布者将消息发送到角色主题中,系统将这些消息传递给多个订阅者。发布/订阅模型的特点在于每个消息可以有多个订阅者,发布者和订阅者之间有时间上的依赖性。针对某个主题的订阅者必须创建一个订阅之后才能消费发布者的消息。为了消费消息,订阅者需要提前订阅该角色主题并保持在线运行。在这种情况下,在订阅者未连接时,发布的消息将在订阅者重新连接时重新发布。
发布订阅的特点在于每个消息可以有多个订阅者,客户端只有订阅后才能接受到消息。发布者和订阅者之间有时间依赖性,接收者和发布者只有建立订阅关系后才能接收到消息。
订阅可分为持久订阅和非持久订阅,持久订阅表示订阅关系建立后消息就不会消失,不管订阅者是否在线。非持久订阅表示订阅者为了接收消息,必须一直在线,当只有一个订阅者时可视为点对点模式。
参考资料