说一说消息队列
什么是消息队列
消息队列(Message Queue,简称MQ),从字面上的意思来看,本质就是一个队列,FIFO(先入先出),只不过队列中存放的内容是Message而已。
消息队列的作用
消息队列主要用于不同进程(Process)/线程(Thread)之间通信。它主要解决两个问题:
- 系统解耦:项目开始时,无法确定最终需求,不同进程间,添加一层,实现解耦,方便今后的扩展
- 消息缓存:系统中,不同进程处理速度不同,MQ,可以实现不同Process之间的缓冲,即写入MQ的速度可以尽可能的块,而处理消息的速度可以适当调整。
消息队列的特性
FIFO
满足队列的FIFO,先入先出策略
可靠性
- 冗余:进程崩溃之后,数据并不会丢失,因为MQ多采用put-get-delete模式,即,仅当确认message被处理完之后,才从MQ中移除Message
- 可恢复:MQ实现解耦,部分进程崩溃,不会拖累整个系统瘫痪。例如,进程B崩溃之后,进程A扔可向MQ添加Message,并等待进程B恢复
可扩展性
- 由于实现解耦,可以很容易调整,消息入队速率,消息处理速率,增加新的进程……
可追踪性
- 数据流的阶段性能定位:获取用户操作的各个阶段(通过Message来标识),捕获不同阶段的耗时,可用于定位系统瓶颈
保证一致性
- 保证MQ中一个message被处理一次,并且只能被处理一次。本质:获取一个message后,这一message即被预定,同一进程不会再一次获取这一Message;当且仅当进程处理完这一Message后,MQ才会delete这个Message。否则,过一段时间后,这一Message自动解除被预定状态,进程能够重新预定这个Message;
异步性
- 很多场景下,MQ不会立即处理Message而是存储Message,并在某一时刻再进行处理。
分布式消息队列
说到分布式就必然牵扯出一系列的话题,负载均衡、服务定位、通信协议、序列化协议…… 不是一两句话就能说明白的。在这里咱们只说有关分布式消息队列的概念。
分布式队列编程模型
分布式队列编程模型包含三类角色:发送者(Sender)、分布式(Queue)、接收者(Receiver)。发送者和接收者分别指的是生产消息和接收消息的应用程序或服务。
点对点模型(Point-to-Point)
基础模型中,只有一个发送这、一个接收者和一个分布式队列。如下图:
生产者消费者模型(Producer-consumer)
如果发送这和接收者都可以有多个部署实例,甚至不同的类型;但是共用同一个队列,就变成了标准的生产者消费者模型。在该模型中,三个角色一般称之为生产者(Producer)、分布式队列(Queue)、消费者(Consumer)。如下图:
发布订阅模型(PubSub)
如果只有一类发送者,发送者将产生的消息实体按照不同的主题(Topic)分发到不同的逻辑队列。每种主题队列对应一类接收者。这就变成了典型的发布订阅模型。在该模型,三个角色被称之为发布者(Publisher)、分布式队列(Queue)、订阅者(Subscriber),如下图:
MVC模型
如果发送者和接收者存在同一个实体中,但是共享一个分布式队列。这就像很经典的MVC模型。如下图
简单的消息队列实现
最后,源码下载
参考资料