MQ(Message Queue)消息队列
什么是MQ
- MQ(Message Queue)消息队列,是基于数据结构中“先进先出”的一种数据结构。简单来说就是在消息传输过程中保存消息对容器。
- 一般用来解决应用解耦,异步消息,流量削峰等问题
- 实现高性能,高可用,可伸缩和最终一致性架构。
为什么使用消息队列
- 在高并发的场景下,由于来不及处理同步请求,请求会发生堵塞。通过消息队列,可以异步的处理请求,缓解系统压力
- 当系统资源有限时,不断的向系统发起请求,超过系统所能处理请求的最大阈值,可能会导致系统崩溃。
- 当发起请求需要立即获得回调信息,而请求的处理需要消费一点的时间时。如:发送邮件,系统下单,模型训练,远程接口调用等
大生产环境下,为什么选择用RabbitMQ之类的消息队列,而不是使用Redis这类可以做队列的NoSql数据库
- 把消息插入NoSql数据库,不如队列的入队出队操作简单
- 频繁的向数据库添加新的消息会增大数据库的负载
- 如果并发的处理数据库,需要对数据库进行上锁或处理会话等操作,甚至可能出现死锁等现象,而使用消息队列不需要考虑这些情况
- 当消息越来越多时,数据库需要定期对消息进行清理
- 消息队列在消费者和生产者中引入了exchange的概念,当压力增长的情况下,可以通过配置exchange在不停机的情况下调整系统资源,缓解服务压力
MQ的实现方式
AMQP
AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。
在AMQP协议中,生产者将消息发送到Exchange中,通过Exchange将消息路由到不同的Queue中,由消费者从Queue中获取消息进行处理。由于Exchange的存在,在消息队列中可以通过配置Exchange将消息发送给不同的队列,缓解调整系统资源。
JMS
JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。
JMS是一种与厂商无关的 API,用来访问收发系统消息,它类似于JDBC(Java Database Connectivity)。这里,JDBC 是可以用来访问许多不同关系数据库的 API,而 JMS 则提供同样与厂商无关的访问方法,以访问消息收发服务。JMS 使您能够通过消息收发服务(有时称为消息中介程序或路由器)从一个 JMS 客户机向另一个 JMS客户机发送消息。JMS消息通常有两种类型:(1)点对点(Point-to-Point)。在点对点的消息系统中,消息分发给一个单独的使用者。点对点消息往往与队列相关联。(2)发布/订阅(Publish/Subscribe)。发布/订阅消息系统支持一个事件驱动模型,消息生产者和消费者都参与消息的传递。生产者发布事件,而使用者订阅感兴趣的事件,并使用事件。该类型消息一般与特定的主题关联。
AMQP和JMS的对比
ANQP
JMS
定义
线级协议
Java API
跨平台
是
否
跨语言
是
否
Model
五种消息模型
- Direct Exchange
- Fanout Exchange
- Topic Exchange
- Headers Exchange
- System Exchange
本质上,后四种消息模型和Publish/Subscribe没有差别,只是在路由机制上做了更细致的划分
两种消息模型
- Point-to-Point
- Publish/Subscribe
消息类型
byte[]
五种消息类型
- Text message
- Object message
- Bytes message
- Stream message
- Map message
消息流
Producer将消息发送到Exchange,Exchange将消息路由到Queue,Consumer从Queue中消费消息。
Producer将消息发送到Queue或者Topic,Consumer从Queue或Topic中消费消息。
综合对比
AMQP定义了线级协议标准;具有跨平台、跨语言特性。
MS 定义了JAVA API层面的标准;在java体系中,多个client均可以通过JMS进行交互,但是其对跨平台、跨语言的支持较差
RabbitMQ和RocketMQ的比较
特性
RabbitMQ
RocketMQ
Prodocer-Comsumer
支持
支持
Publish- Subscribe
支持
支持
Request-Reply(请求回复)
支持
API完备性
高
高
多语言支持
语言无关
只支持Java
单机吞吐量
万级
万级
消息延迟
微秒级
毫秒级
可用性
高(主从)
非常高(分布式)
消息丢失
低
低
消息重复
可控制
文档完备性
高
中
部署难度
低
部署方式
独立
独立
社区活跃
高
中
商业支持
无
阿里云
特点
并发能力强
分布式扩展设计,多种消费模式,支持上万个队列,性能好
支持协议
AMOP
基于JMS的自定义协议(社区提供的JMS不成熟)
持久化
内存、文件
磁盘文件
事务
支持
支持
负载均衡
支持
支持
管理界面
好
有web console实现
评价
- 优点
- MQ性能好
- 管理界面丰富
- 支持AMQP协议,跨平台能力强
- 缺点
- erlang语言难度较大
- 集群不支持动态扩展
- 优点
- 模型简单,接口易用
- 在阿里有大规模的应用
- 性能好
- 支持多种消费
- 开发度活跃,版本更新较快
- 缺点
- 产品较新,文档缺乏
- 基于自己的一套协议,兼容性差