消息队列、RabbitMQ和RocketMQ

消息队列、RabbitMQ和RocketMQ

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语言难度较大
    • 集群不支持动态扩展
  • 优点
    • 模型简单,接口易用
    • 在阿里有大规模的应用
    • 性能好
    • 支持多种消费
    • 开发度活跃,版本更新较快
  • 缺点
    • 产品较新,文档缺乏
    • 基于自己的一套协议,兼容性差
Licensed under CC BY-NC-SA 4.0
陕ICP备2023020057号
Built with Hugo
主题 Stack 由 Jimmy 设计