消息队列RabbitMQ和RocketMQ

Posted 北溪入江流

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了消息队列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的对比

ANQPJMS
定义线级协议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的比较

特性RabbitMQRocketMQ
Prodocer-Comsumer支持支持
Publish- Subscribe支持支持
Request-Reply(请求回复)支持
API完备性
多语言支持语言无关只支持Java
单机吞吐量万级万级
消息延迟微秒级毫秒级
可用性高(主从)非常高(分布式)
消息丢失
消息重复可控制
文档完备性
部署难度
部署方式独立独立
社区活跃
商业支持阿里云
特点并发能力强分布式扩展设计,多种消费模式,支持上万个队列,性能好
支持协议AMOP基于JMS的自定义协议(社区提供的JMS不成熟)
持久化内存、文件磁盘文件
事务支持支持
负载均衡支持支持
管理界面有web console实现
评价
  • 优点
    • MQ性能好
    • 管理界面丰富
    • 支持AMQP协议,跨平台能力强
  • 缺点
    • erlang语言难度较大
    • 集群不支持动态扩展
  • 优点
    • 模型简单,接口易用
    • 在阿里有大规模的应用
    • 性能好
    • 支持多种消费
    • 开发度活跃,版本更新较快
  • 缺点
    • 产品较新,文档缺乏
    • 基于自己的一套协议,兼容性差

MQ选型对比ActiveMQ,RabbitMQ,RocketMQ,Kafka 消息队列框架选哪个?

最近研究消息队列,发现好几个框架,搜罗一下进行对比,说一下选型说明:

1)中小型软件公司,建议选RabbitMQ。一方面,erlang语言天生具备高并发的特性,而且他的管理界面用起来十分方便。不考虑rocketmq和kafka的原因是,一方面中小型软件公司不如互联网公司,数据量没那么大,选消息中间件,应首选功能比较完备的,所以kafka排除。RocketMQ也很不错,只是没有RabbitMQ出来的早,文档和网上的资料没有RabbitMQ多,但也是很不错,RocketMQ是阿里出品,现在阿里已经把RocketMQ捐赠给Apache了,维护和更新不是问题 。

2)大型软件公司,根据具体使用在rocketMq和kafka之间二选一。一方面,大型软件公司,具备足够的资金搭建分布式环境,也具备足够大的数据量。针对rocketMQ,大型软件公司也可以抽出人手对rocketMQ进行定制化开发,毕竟国内有能力改JAVA源码的人,还是相当多的。至于kafka,根据业务场景选择,如果有日志采集功能,肯定是首选kafka了。具体该选哪个,看使用场景

(上面观点都是个人意见,仅供参考)

特性

ActiveMQ

RabbitMQ

RocketMQ

kafka

开发语言

java

erlang

java

scala

单机吞吐量

万级

万级

10万级

10万级

时效性

ms级

us级

ms级

ms级以内

可用性

高(主从架构)

高(主从架构)

非常高(分布式架构)

非常高(分布式架构)

功能特性

成熟的产品,在很多公司得到应用;有较多的文档;各种协议支持较好

基于erlang开发,所以并发能力很强,性能极其好,延时很低;管理界面较丰富

MQ功能比较完备,扩展性佳

只支持主要的MQ功能,像一些消息查询,消息回溯等功能没有提供,毕竟是为大数据准备的,在大数据领域应用广。

 

ActiveMQ、Kafka、RocketMQ、RabbitMQ比较

 1.ActiveMQ

优点

 单机吞吐量:万级

 topic数量都吞吐量的影响:

 时效性:ms级

 可用性:高,基于主从架构实现高可用性

 消息可靠性:有较低的概率丢失数据

 功能支持:MQ领域的功能极其完备

缺点:

官方社区现在对ActiveMQ 5.x维护越来越少,较少在大规模吞吐的场景中使用。

 

2.Kafka

号称大数据的杀手锏,谈到大数据领域内的消息传输,则绕不开Kafka,这款为大数据而生的消息中间件,以其百万级TPS的吞吐量名声大噪,迅速成为大数据领域的宠儿,在数据采集、传输、存储的过程中发挥着举足轻重的作用。

Apache Kafka它最初由LinkedIn公司基于独特的设计实现为一个分布式的提交日志系统( a distributed commit log),之后成为Apache项目的一部分。

目前已经被LinkedIn,Uber, Twitter, Netflix等大公司所采纳。

优点

 性能卓越,单机写入TPS约在百万条/秒,最大的优点,就是吞吐量高。

 时效性:ms级

 可用性:非常高,kafka是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用

 消费者采用Pull方式获取消息, 消息有序, 通过控制能够保证所有消息被消费且仅被消费一次;

 有优秀的第三方Kafka Web管理界面Kafka-Manager;

 在日志领域比较成熟,被多家公司和多个开源项目使用;

 功能支持:功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用

缺点:

 Kafka单机超过64个队列/分区,Load会发生明显的飙高现象,队列越多,load越高,发送消息响应时间变长

 使用短轮询方式,实时性取决于轮询间隔时间;

 消费失败不支持重试;

 支持消息顺序,但是一台代理宕机后,就会产生消息乱序;

 社区更新较慢;

 

3.RabbitMQ

RabbitMQ 2007年发布,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息系统,是当前最主流的消息中间件之一。

RabbitMQ优点:

 由于erlang语言的特性,mq 性能较好,高并发;

 吞吐量到万级,MQ功能比较完备  

 健壮、稳定、易用、跨平台、支持多种语言、文档齐全;

 开源提供的管理界面非常棒,用起来很好用  

 社区活跃度高;

RabbitMQ缺点:

 erlang开发,很难去看懂源码,基本职能依赖于开源社区的快速维护和修复bug,不利于做二次开发和维护。

 RabbitMQ确实吞吐量会低一些,这是因为他做的实现机制比较重。  

 需要学习比较复杂的接口和协议,学习和维护成本较高。

 

4.RocketMQ

RocketMQ出自 阿里公司的开源产品,用 Java 语言实现,在设计时参考了 Kafka,并做出了自己的一些改进。

RocketMQ在阿里集团被广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理,binglog分发等场景。

 

RocketMQ优点:

 单机吞吐量:十万级

 可用性:非常高,分布式架构

 消息可靠性:经过参数优化配置,消息可以做到0丢失

 功能支持:MQ功能较为完善,还是分布式的,扩展性好

 支持10亿级别的消息堆积,不会因为堆积导致性能下降

 源码是java,我们可以自己阅读源码,定制自己公司的MQ,可以掌控 

RocketMQ缺点:

 支持的客户端语言不多,目前是java及c++,其中c++不成熟;

 社区活跃度一般

 没有在 mq 核心中去实现JMS等接口,有些系统要迁移需要修改大量代码 

 

以上是关于消息队列RabbitMQ和RocketMQ的主要内容,如果未能解决你的问题,请参考以下文章

RabbitMQ 消息队列

(转)RabbitMQ消息队列-RabbitMQ消息队列架构与基本概念

Rabbitmq 消息队列

rabbitmq的延迟消息队列实现

Golang调用Rabbitmq消息队列和封装

RabbitMQ消息队列