消息队列的选型
消息列队是什么?
消息队列是在消息的传输过程中保存消息的容器。(百度百科)
为什么要使用消息队列?
优点与应用:异步处理,应用解耦,错峰与流控,消息通讯,数据分发,失败重试,日志处理
缺点:
-
系统可用性降低,系统复杂性提高,一致性问题,
-
需要强一致性,关注业务逻辑的处理结果,则RPC显得更为合适
-
需要强事务保证而且延迟敏感的,RPC是优于消息队列的
消息队列使用总结
-
消息队列不是万能的,对于需要强事务保证而且延迟敏感的,RPC是优于消息队列的。
-
对于一些无关痛痒,或者对于别人非常重要但是对于自己不是那么关心的事情,可以利用消息队列去做。
-
支持最终一致性的消息队列,能够用来处理延迟不那么敏感的“分布式事务”场景,而且相对于笨重的分布式事务,可能是更优的处理方式。
-
当上下游系统处理能力存在差距的时候,利用消息队列做一个通用的“漏斗”,在下游有能力处理的时候,再进行分发。
-
如果下游有很多系统关心你的系统发出的通知的时候,果断地使用消息队列吧。
应该选用哪种消息队列?
常见消息队列中间件的对比:
消息 队列 |
开发语言 |
协议支持 |
设计模式 |
持久化支持 |
事务支持 |
负载均衡支持 |
功能特点 |
缺点 |
RabbitMQ |
Erlang |
AMQP,XMPP,SMTP,STOMP |
代理(Broker)模式(消息在发送给客户端时先在中心队列排队) |
支持持久化到文件 |
不支持 |
支持 |
性能较好;管理界面较丰富;在互联网公司有较大规模的应用; |
虽然产品开源,但Erlang语言应用不够普遍; |
ZeroMQ |
C++ |
ZeroMQ是一个并发框架做的socket库 |
点对点模式,通过引用ZeroMQ程序库, |
不支持 |
不支持 |
不支持 |
低延时,高性能,最高每秒43万条消息 |
非持久性队列,宕机后数据将会丢失 |
ActiveMQ |
Java |
OpenWire,Stomp REST,WS Notification,XMPP,AMQP,JMS |
支持代理模式,也支持点对点模式 |
支持持久化到文件或数据库 |
支持 |
支持 |
成熟的产品,在很多公司得到应用;有较多的文档;各种协议支持较好, |
根据其他用户反馈,会出现丢失消息的问题; |
系统吞吐量(TPS)比较:
MQ |
TPS量级(持久化) |
场景 |
备注 |
RabbitMQ |
3500-4000msg/s |
非海量高可靠性场景 大规模企业应用、ESB 复杂路由策略 异构系统整合 |
协议丰富兼容性强,功能完善,消息格式比较大,速度较慢,消息持久化对性能影响明显 |
ZeroMq |
大于800000msg/s |
高并发连接场景,如:在线游戏 海量高实时性场景,如:股票行情 |
偏重于网络开发,开发成本高,高级功能需自行实现,不建议做传统MQ应用 |
ActiveMq |
~3600msg/s |
非海量高可靠场景 企业级应用 分布式事务(XA) 异构系统整合 |
相对Rabbitmq较轻量级,性能相近,完整JMS支持、配置较复杂 |
Redis |
~15000msg/s |
高吞吐低延迟 大量小消息体(<10K) 顺序性或排序要求 异构系统整合 |
轻量级MQ的快速简单实现,容灾与负载等功能需自行完善 |
Kafka |
Input ~70000msg/s Output >150000msg/s |
日志等海量数据流 DB数据同步 高堆积离线消息处理 |
非典型MQ,更偏重于流式数据批处理 |
-
高并发
- 毫无疑问KAFKA发消息的速度是最快的
- ROCKETMQ/ONS次之
- rabbitmq最慢
-
高可用
- 这几种都能做MASTER/SLAVE,跨机房的高可用
- KAFKA复制有很多坑,所以这个分数要降低
-
所需要的节点数量
- KAFKA集群环境下,需要依赖zk, zk至少3个节点,再加上kafka的至少3个节点,那就是6个
- ROCKETMQ集群环境下,虽然不依赖zk,但是需要name server,至少2个节点,2个MASTER,就是4个
- RABBITMQ集群环境下,不依赖zk,只要3个erlang node,就是3个
-
全局顺序消费
- KAFKA只要在分区是1个情况下才能大致的做到全局消费的顺序
- ROCKETMQ/ONS同上,只是变成了另外一个术语
- RABBITMQ能大致保证全局顺序消费
- 以上所讲的都是消息没有被拒绝或者消息处理失败重新回到队列的情况
-
其他功能-流控
- 只有RabbitMQ有
-
其他功能-优先级队列
- RabbitMQ对优先级队列支持最完善
消息队列组件简介
RabbitMQ
RabbitMQ是使用Erlang编写的一个开源的消息队列,本身支持很多的协议:AMQP,XMPP, SMTP, STOMP,也正因如此,它非常重量级,更适合于企业级的开发。同时实现了Broker构架,这意味着消息在发送给客户端时先在中心队列排队。对路由,负载均衡或者数据持久化都有很好的支持。社区活跃度比较活跃,可视化界面。缺点就是数据吞吐量相对与小一些,并且是基于erlang语言开发,比较重的问题难以维护。
rocketMq
rocketMq几十万级别数据量,基于Java开发,应对了淘宝双十一考验,并且文档十分的完善,拥有一些其他消息队列不具备的高级特性,如定时推送,其他消息队列是延迟推送,如rabbitMq通过设置expire字段设置延迟推送时间。又比如rocketmq实现分布式事务,比较可靠的。
Redis
Redis是一个基于Key-Value对的NoSQL数据库,开发维护很活跃。虽然它是一个Key-Value数据库存储系统,但它本身支持MQ功能,所以完全可以当做一个轻量级的队列服务来使用。对于RabbitMQ和Redis的入队和出队操作,各执行100万次,每10万次记录一次执行时间。测试数据分为128Bytes、512Bytes、1K和10K四个不同大小的数据。实验表明:入队时,当数据比较小时Redis的性能要高于RabbitMQ,而如果数据大小超过了10K,Redis则慢的无法忍受;出队时,无论数据大小,Redis都表现出非常好的性能,而RabbitMQ的出队性能则远低于Redis。
ZeroMQ
ZeroMQ号称最快的消息队列系统,尤其针对大吞吐量的需求场景。ZMQ能够实现RabbitMQ不擅长的高级/复杂的队列,但是开发人员需要自己组合多种技术框架,技术上的复杂度是对这MQ能够应用成功的挑战。ZeroMQ具有一个独特的非中间件的模式,你不需要安装和运行一个消息服务器或中间件,因为你的应用程序将扮演了这个服务角色。你只需要简单的引用ZeroMQ程序库,可以使用NuGet安装,然后你就可以愉快的在应用程序之间发送消息了。但是ZeroMQ仅提供非持久性的队列,也就是说如果down机,数据将会丢失。其中,Twitter的Storm中默认使用ZeroMQ作为数据流的传输。
ActiveMQ
ActiveMQ是Apache下的一个子项目。 类似于ZeroMQ,它能够以代理人和点对点的技术实现队列。同时类似于RabbitMQ,它少量代码就可以高效地实现高级应用场景。
Kafka/Jafka
Kafka是Apache下的一个子项目,是一个高性能跨语言分布式Publish/Subscribe消息队列系统,而Jafka是在Kafka之上孵化而来的,即Kafka的一个升级版。具有以下特性:快速持久化,可以在O(1)的系统开销下进行消息持久化;高吞吐,在一台普通的服务器上既可以达到10W/s的吞吐速率;完全的分布式系统,Broker、Producer、Consumer都原生自动支持分布式,自动实现复杂均衡;支持Hadoop数据并行加载,对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka通过Hadoop的并行加载机制来统一了在线和离线的消息处理。Apache Kafka相对于ActiveMQ是一个非常轻量级的消息系统,除了性能非常好之外,还是一个工作良好的分布式系统。kafka真正的大规模分布式消息队列,提供的核心功能比较少。基于zookeeper实现的分布式消息订阅。
结论1
-
Rabbitmq很适用于小团队和高并发不是很突出的地方,并且团队希望尽量自动化
-
牵涉到高并发,并且是业务消息要用rocketmq/ons
-
牵涉到高并发,但不是业务消息的用kafka
结论2
一般的业务系统要引入 MQ,最早大家都用 ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,所以大家还是算了吧,我个人不推荐用这个了;
后来大家开始用 RabbitMQ,但是确实 erlang 语言阻止了大量的 Java 工程师去深入研究和掌控它,对公司而言,几乎处于不可控的状态,但是确实人家是开源的,比较稳定的支持,活跃度也高;
不过现在确实越来越多的公司会去用 RocketMQ,确实很不错,毕竟是阿里出品,但社区可能有突然黄掉的风险(目前 RocketMQ 已捐给 Apache,但 GitHub 上的活跃度其实不算高)对自己公司技术实力有绝对自信的,推荐用 RocketMQ,否则回去老老实实用 RabbitMQ 吧,人家有活跃的开源社区,绝对不会黄。
所以中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。
如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。
说明:本文内容来自于网络,是从网络搜索、摘抄、整理、汇集而成。
博主简介:佘焕敏(shé),洋名 Billy Sir。
关注编程基础技术,并致力于研究软件的自动化生成。 对编程规范化、面向对象的极致使用也有着浓厚的兴趣。 同时非常希望能够写程序到65岁。
只有工匠精神,才能把常人觉得单调乏味的代码,当作作品雕刻成艺术品。
重点:这里几乎每一篇文章,都是我认真创作的,凝结了心血。写作从来都不是一件容易的事,对从小语文不好的我而言,是难上加难。而且,你发现没有,文中没有广告。这篇文章介绍了为什么要写这些文章。
![微信赞赏码](https://img2022.cnblogs.com/blog/33556/202211/33556-20221101085333455-1717538163.png)