号称最快的消息队列系统,尤为针对大吞吐量的需求场景。前端
扩展性好,开发比较灵活,采用C语言实现,实际上只是一个socket库的从新封装,若是作为消息队列使用,须要开发大量的代码。ZeroMQ仅提供非持久性的队列,也就是说若是down机,数据将会丢失。其中,Twitter的Storm中使用ZeroMQ做为数据流的传输。spring
结合erlang语言自己的并发优点,支持不少的协议:AMQP,XMPP, SMTP, STOMP,也正是如此,使的它变的很是重量级,更适合于企业级的开发。数据库
性能较好,可是不利于作二次开发和维护。服务器
历史悠久的开源项目,是Apache下的一个子项目。已经在不少产品中获得应用,实现了JMS1.1规范,能够和spring-jms轻松融合,实现了多种协议,不够轻巧(源代码比RocketMQ多),支持持久化到数据库,对队列数较多的状况支持很差。网络
作为一个基于内存的K-V数据库,其提供了消息订阅的服务,能够看成MQ来使用,目前应用案例较少,且不方便扩展。对于RabbitMQ和Redis的入队和出队操做,各执行100万次,每10万次记录一次执行时间。并发
测试数据分为 128Bytes、512Bytes、1K和10K四个不一样大小的数据。负载均衡
实验代表:入队时,当数据比较小时Redis的性能要高于RabbitMQ,而如 果数据大小超过了10K,Redis则慢的没法忍受;出队时,不管数据大小,Redis都表现出很是好的性能,而RabbitMQ的出队性能则远低于 Redis。socket
Kafka是Apache下的一个子项目,是一个高性能跨语言分布式发布/订阅消息队列系统,而Jafka是在Kafka之上孵化而来的,即Kafka的一个升级版。分布式
具备如下特性:oop
当你须要使用消息队列时,首先须要考虑它的必要性。
可使用mq的场景有不少,最经常使用的几种:
反之,若是须要强一致性,关注业务逻辑的处理结果,则RPC显得更为合适。
解耦是消息队列要解决的最本质问题。所谓解耦,简单点讲就是一个事务,只关心核心的流程。而须要依赖其余系统但不那么重要的事情,有通知便可,无需等待结果。换句话说,基于消息的模型,关心的是“通知”,而非“处理”。
举一个例子,关于订单系统,订单最终支付成功以后可能须要给用户发送短信积分什么的,但其实这已经不是咱们系统的核心流程了。
若是外部系统速度偏慢(好比短信网关速度很差),那么主流程的时间会加长不少,用户确定不但愿点击支付过好几分钟才看到结果。那么咱们只须要通知短信系统“咱们支付成功了”,不必定非要等待它当即处理完成。
最终一致性指的是两个系统的状态保持一致,要么都成功,要么都失败。
固然有个时间限制,理论上越快越好,但实际上在各类异常的状况下,可能会有必定延迟达到最终一致状态,但最后两个系统的状态是同样的。
业界有一些为“最终一致性”而生的消息队列,如:
其设计初衷,就是为了交易系统中的高可靠通知。
以一个银行的转帐过程来理解最终一致性,转帐的需求很简单,若是A系统扣钱成功,则B系统加钱必定成功。反之则一块儿回滚,像什么都没发生同样。
然而,这个过程当中存在不少可能的意外:
可见,想把这件看似简单的事真正作成,真的不那么容易。
全部跨VM的一致性问题,从技术的角度讲通用的解决方案是:
最终一致性不是消息队列的必备特性,但确实能够依靠消息队列来作最终一致性的事情。
另外,全部不保证100%不丢消息的消息队列,理论上没法实现最终一致性。好吧,应该说理论上的100%,排除系统严重故障和bug。
像Kafka一类的设计,在设计层面上就有丢消息的可能(好比定时刷盘,若是掉电就会丢消息)。哪怕只丢千分之一的消息,业务也必须用其余的手段来保证结果正确。
消息队列的基本功能之一是进行广播。
若是没有消息队列,每当一个新的业务方接入,咱们都要联调一次新接口。有了消息队列,咱们只须要关心消息是否送达了队列,至于谁但愿订阅,是下游的事情,无疑极大地减小了开发和联调的工做量。
好比本文开始提到的产品中心发布产品变动的消息,以及景点库不少去重更新的消息,可能“关心”方有不少个,但产品中心和景点库只须要发布变动消息便可,谁关心谁接入。
试想上下游对于事情的处理能力是不一样的。
好比,Web前端每秒承受上千万的请求,并非什么神奇的事情,只须要加多一点机器,再搭建一些LVS负载均衡设备和Nginx等便可。
但数据库的处理能力却十分有限,即便使用SSD加分库分表,单机的处理能力仍然在万级。因为成本的考虑,咱们不能奢求数据库的机器数量追上前端。
这种问题一样存在于系统和系统之间,如短信系统可能因为短板效应,速度卡在网关上(每秒几百次请求),跟前端的并发量不是一个数量级。
但用户晚上个半分钟左右收到短信,通常是不会有太大问题的。若是没有消息队列,两个系统之间经过协商、滑动窗口等复杂的方案也不是说不能实现。
但系统复杂性指数级增加,势必在上游或者下游作存储,而且要处理定时、拥塞等一系列问题。并且每当有处理能力有差距的时候,都须要单独开发一套逻辑来维护这套逻辑。因此,利用中间系统转储两个系统的通讯内容,并在下游系统有能力处理这些消息的时候,再处理这些消息,是一套相对较通用的方式。
1.消息队列不是万能的,对于须要强事务保证并且延迟敏感的,RPC是优于消息队列的。
2.对于一些无关痛痒,或者对于别人很是重要可是对于本身不是那么关心的事情,能够利用消息队列去作。
3.支持最终一致性的消息队列,可以用来处理延迟不那么敏感的“分布式事务”场景,并且相对于笨重的分布式事务,多是更优的处理方式。
4.当上下游系统处理能力存在差距的时候,利用消息队列作一个通用的“漏斗”,在下游有能力处理的时候,再进行分发。
5.若是下游有不少系统关心你的系统发出的通知的时候,果断地使用消息队列吧。
本文由博客一文多发平台 OpenWrite 发布!