什么是消息队列
消息队列(Message Queue) 简称MQ是一种先进先出的队列型数据结构,实际上是系统内核中的一个内部链表。拥有权限的进程可以向消息队列中写入或读取消息,消息被顺序插入队列中,其中发送进程将消息添加到队列末尾,接受进程从队列头读取消息。
为什么要使用MQ
消息队列的优点
- 屏蔽异构平台的细节,发送方和接收方不需要了解对方的系统,只需要认识信息就够了;
- 异步:消息可以堆积在队列中,发送方和接收方不需要同时在线,也不需要同时扩容。
- 削峰:在系统请求量/并发量高的情况下,如果我们直接把这些请求打到列如MySQL上,很有可能直接就打死。
- 解耦:由于发送方和接收方没有直接依赖,可以直接灵活增加or修改模块,提高系统的可扩展性,这点在分布式系统中尤为重要。
总结一下
- 在特殊场景下,比如高并发、高可用、分布式等情况下,使用消息队列可以提高系统性能和稳定性。
- 在事件驱动架构中,使用消息队列可以实现发布-订阅模式,让不同的模块之间可以相互通信和协作。
消息协议
消息队列要在网络中进行通信,那就需要采用一种通信协议。
AMQP、MQTT和STOMP是三种最常见、最流行的基于TCP/IP的消息传递协议。
AMQP
高级消息队列协议,即Advanced Message Queuing Protocol(AMQP),一个提供统一消息服务的应用层标准 高级消息队列协议(二进制应用层协议),是应用层协议的一个开放标准,为面向消息的中间件设计,兼容 JMS。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件同产品,不同的开发语言等条件的限制。
MQTT
消息队列遥测传输协议,即Message Queuing Telemetry Transport(MQTT),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,由IBM在1999年发布。议由于其轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。
STOMP
简单(或流式)文本消息协议,Simple (or Streaming) Text Oriented Messaging Protoco(STOMP) 协议是一种基于帧的协议,它可以让不同的客户端通过一个中间服务器进行异步消息传递。它是一个简单的可互操作的协议,它的设计灵感来源于 HTTP 的简单性。STOMP 协议支持发布-订阅和点对点两种消息模式。STOMP 协议可以用于多种语言和平台,例如 Java、Python、Ruby、JavaScript 等。
消息队列模型
MQ最简单的模型就三个角色。
消息队列:存储消息。生产者:发送消息到消息队列。消费者:从消息队列获取消息并处理消息。
队列模型
它允许多个生产者往同一个队列发送消息。但多个消费者之间是竞争的关系,也就是说一条消息只能被其中一个消费者接收到,读完即被删除。
发布订阅模型
那如果我们要将消息发送给多个消费者,或者是被多个消费者消费,那简单的队列模型显然无法做到。
如果我们硬要用队列模型也不是不可以。我们可以为每一个消费者单独创建一个队列,让生产者发送多份信息给消费者的消费队列。但是这样也会存在很多问题。生产者必须事先知道那些消费者需要这个信息。而且在创建了许多相同的信息,造成了资源的浪费。
为了解决这个问题,就演化出了另外一种消息模型:发布-订阅模型。
在发布-订阅模型中,消息的发送方称为发布者(Publisher),消息的接收方称为订阅者(Subscriber), 服务端存放消息的容器称为主题(Topic)。发布者将消息发送到主题中,订阅者在接收消息之前需要先「订阅主题」。「订阅」在这里既是一个动作,同时还可以认为是主题在消费时的一个逻辑副本,每份订阅中,订阅者都可以接收到主题的所有消息。
实际上,在这种发布-订阅模型中,如果只有一个订阅者,那它和队列模型就基本是一样的了。也就是说,发布-订阅模型在功能层面上是可以兼容队列模型的。(这两种消息模型其实并没有本质上的区别,都可以通过一些扩展或者变化来互相替代
发布-订阅模型和队列模型的唯一不同点在于:一份消息数据是否可以被多次消费。