2019第1周日-MQ选型要点

用消息中间件犹如小马过河,选择合适的才最重要,这须要贴合自身的业务需求,技术服务于业务。具体在选择上可从下面功能、性能、可靠性和可用性、运维管理、社区和生态、团队技术栈等维度来进行筛选。html

具体技术选型指标1:功能ios

首要的就是功能维度,这个直接决定了你可否最大程度上的实现开箱即用,进而缩短项目周期、下降成本等。若是一款消息中间件的功能达不到想要的功能,那么就须要进行二次开发,这样会增长项目的技术难度、复杂度以及增大项目周期等。程序员

功能维度又能够划分个多个子维度,大体能够分为如下这些。编程

  1. 优先级队列:优先级高的消息先被消费,若消费速度大于生产速度,MQ中没消息堆积,那没多大意义;
  2. 延迟队列:延迟队列存储的是对应的延迟消息,所谓“延迟消息”是指当消息被发送之后,并不想让消费者马上拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。
  3. 死信队列:存没法被正确投递消费的消息,避免不能消费的回退消息放在队列顶部,不断被处理和回滚陷入死循环。
  4. 重试队列:指消费端消费消息失败时,为防止消息无端丢失而从新将消息回滚到 Broker 中。通常分红多个重试等级,每一个重试等级通常也会设置从新投递延时,重试次数越多投递延时就越大。为此须要设置一个上限,超过投递次数就入死信队列。
  5. 消费模式:消费模式分为推(push)模式和拉(pull)模式。推模式是指由 Broker 主动推送消息至消费端,实时性较好,不过须要必定的流制机制来确保服务端推送过来的消息不会压垮消费端。而拉模式是指消费端主动向 Broker 端请求拉取(通常是定时或者定量)消息,实时性较推模式差,可是能够根据自身的处理能力而控制拉取的消息量。
  6. 广播消费:消息通常有两种传递模式:点对点(P2P,Point-to-Point)模式和发布 / 订阅(Pub/Sub)模式。
  7. 消息回溯:指消息在消费完成以后,还能消费到以前被消费掉的消息。对于消息而言,常常面临的问题是“消息丢失”,至因而真正因为消息中间件的缺陷丢失仍是因为使用方的误用而丢失通常很难追查,若是消息中间件自己具有消息回溯功能的话,能够经过回溯消费复现“丢失的”消息进而查出问题的源头之所在。消息回溯的做用远不止与此,好比还有索引恢复、本地缓存重建,有些业务补偿方案也能够采用回溯的方式来实现。
  8. 消息堆积 + 持久化:流量削峰是消息中间件的一个很是重要的功能,而这个功能其实得益于其消息堆积能力。消息堆积份内存式堆积和磁盘式堆积。RabbitMQ 是典型的内存式堆积,但这并不是绝对,在某些条件触发后会有换页动做来将内存中的消息换页到磁盘(换页动做会影响吞吐),或者直接使用惰性队列来将消息直接持久化至磁盘中。Kafka 是一种典型的磁盘式堆积,全部的消息都存储在磁盘中。
  9. 消息追踪:对于分布式架构系统中的链路追踪(trace)而言,你们必定不会陌生。对于消息中间件而言,消息的链路追踪(如下简称消息追踪)一样重要。对于消息追踪最通俗的理解就是要知道消息从哪来,存在哪里以及发往哪里去。基于此功能下,咱们能够对发送或者消费完的消息进行链路追踪服务,进而能够进行问题的快速定位与排查。
  10. 消息过滤:消息过滤是指按照既定的过滤规则为下游用户提供指定类别的消息。就以 kafka 而言,彻底能够将不一样类别的消息发送至不一样的 topic 中,由此能够实现某种意义的消息过滤,或者 Kafka 还能够根据分区对同一个 topic 中的消息进行分类。不过更加严格意义上的消息过滤应该是对既定的消息采起必定的方式按照必定的过滤规则进行过滤。
  11. 多租户:重租赁技术,是一种软件架构技术,主要用来实现多用户的环境下公用相同的系统或程序组件,而且仍能够确保各用户间数据的隔离性。RabbitMQ 就可以支持多租户技术,每个租户表示为一个 vhost,其本质上是一个独立的小型 RabbitMQ 服务器,又有本身独立的队列、交换器及绑定关系等,而且它拥有本身独立的权限。vhost 就像是物理机中的虚拟机同样,它们在各个实例间提供逻辑上的分离,为不一样程序安全保密地容许数据,它既能将同一个 RabbitMQ 中的众多客户区分开,又能够避免队列和交换器等命名冲突。
  12. 多协议支持:为了让生产者和消费者都能理解所承载的信息(生产者须要知道如何构造消息,消费者须要知道如何解析消息),它们就须要按照一种统一的格式描述消息,这种统一的格式称之为消息协议。有效的消息必定具备某种格式,而没有格式的消息是没有意义的。通常消息层面的协议有 AMQP、MQTT、STOMP、XMPP 等(消息领域中的 JMS 更多的是一个规范而不是一个协议),支持的协议越多其应用范围就会越广,通用性越强,好比 RabbitMQ 可以支持 MQTT 协议就让其在物联网应用中得到一席之地。还有的消息中间件是基于其自己的私有协议运转的,典型的如 Kafka。
  13. 跨语言支持:消息中间件自己具有应用解耦的特性,若是可以进一步的支持多客户端语言,那么就能够将此特性的效能扩大。跨语言的支持力度也能够从侧面反映出一个消息中间件的流行程度。
  14. 流量控制:流量控制(flow control)针对的是发送方和接收方速度不匹配的问题,提供一种速度匹配服务抑制发送速率使接收方应用程序的读取速率与之相适应。一般的流控方法有 Stop-and-wait、滑动窗口以及令牌桶等。
  15. 消息顺序性:指保证消息有序。这个功能有个很常见的应用场景就是 CDC(Change Data Chapture)。
  16. 安全机制:身份认证是指客户端与服务端链接进行身份认证,权限控制是指对客户端的读写操做进行权限控制。
  17. 消息幂等性:消息在生产者和消费者之间进行传输而言通常有三种传输保障(delivery guarantee):At most once,至多一次,消息可能丢失,但毫不会重复传输;At least once,至少一次,消息毫不会丢,可是可能会重复;Exactly once,精确一次,每条消息确定会被传输一次且仅一次。对于确保对于大多数消息中间件而言,通常只提供 At most once 和 At least once 两种传输保障,对于第三种通常很难作到,由此消息幂等性也很难保证。不过若是要考虑全局的幂等,还须要与从上下游方面综合考虑,即关联业务层面,幂等处理自己也是业务层面所须要考虑的重要议题。如下游消费者层面为例,有可能消费者消费完一条消息以后没有来得及确认消息就发生异常,等到恢复以后又得从新消费原来消费过的那条消息,那么这种类型的消息幂等是没法有消息中间件层面来保证的。若是要保证全局的幂等,须要引入更多的外部资源来保证,好比以订单号做为惟一性标识,而且在下游设置一个去重表。
  18. 事务性消息:支持事务的消息中间件并不在少数,Kafka 和 RabbitMQ 都支持,不过此二者的事务是指生产者发生消息的事务,要么发送成功,要么发送失败。消息中间件能够做为用来实现分布式事务的一种手段,但其自己并不提供全局分布式事务的功能。

具体技术选型指标2:性能缓存

功能维度是消息中间件选型中的一个重要的参考维度,但这并非惟一的维度。有时候性能比功能还要重要,何况性能和功能不少时候是相悖的,鱼和熊掌不可兼得,Kafka 在开启幂等、事务功能的时候会使其性能下降,RabbitMQ 在开启 rabbitmq_tracing 插件的时候也会极大的影响其性能。消息中间件的性能通常是指其吞吐量,虽然从功能维度上来讲,RabbitMQ 的优点要大于 Kafka,可是 Kafka 的吞吐量要比 RabbitMQ 高出 1 至 2 个数量级,通常 RabbitMQ 的单机 QPS 在万级别以内,而 Kafka 的单机 QPS 能够维持在十万级别,甚至能够达到百万级。安全

消息中间件的吞吐量始终会受到硬件层面的限制。就以网卡带宽为例,若是单机单网卡的带宽为 1Gbps,若是要达到百万级的吞吐,那么消息体大小不得超过 (1Gb/8)/100W,即约等于 134B,换句话说若是消息体大小超过 134B,那么就不可能达到百万级别的吞吐。这种计算方式一样能够适用于内存和磁盘。性能优化

时延做为性能维度的一个重要指标,却每每在消息中间件领域所被忽视,由于通常使用消息中间件的场景对时效性的要求并非很高,若是要求时效性彻底能够采用 RPC 的方式实现。消息中间件具有消息堆积的能力,消息堆积越大也就意味着端到端的时延也就越长,与此同时延时队列也是某些消息中间件的一大特点。那么为何还要关注消息中间件的时延问题呢?消息中间件可以解耦系统,对于一个时延较低的消息中间件而言,它可让上游生产者发送消息以后能够迅速的返回,也可让消费者更加快速的获取到消息,在没有堆积的状况下可让总体上下游的应用之间的级联动做更加高效,虽然不建议在时效性很高的场景下使用消息中间件,可是若是所使用的消息中间件的时延方面比较优秀,那么对于总体系统的性能将会是一个不小的提高。服务器

具体技术选型指标3:可靠性 + 可用性网络

消息丢失是使用消息中间件时所不得不面对的一个同点,其背后消息可靠性也是衡量消息中间件好坏的一个关键因素。尤为是在金融支付领域,消息可靠性尤其重要。然而说到可靠性必然要说到可用性,注意这二者之间的区别,消息中间件的可靠性是指对消息不丢失的保障程度;而消息中间件的可用性是指无端障运行的时间百分比,一般用几个 9 来衡量。架构

不少时候,对于可靠性方面也容易存在一个误区: 想要找到一个产品来保证消息的绝对可靠,很不幸的是这世界上没有绝对的东西,只能说尽可能趋于完美 想要尽量的保障消息的可靠性也并不是单单只靠消息中间件自己,还要依赖于上下游,须要从生产端、服务端和消费端这 3 个维度去努力保证,《RabbitMQ 消息可靠性分析》这篇文章就从这 3 个维度去分析了 RabbitMQ 的可靠性。

从狭义的角度来讲,分布式系统架构是一致性协议理论的应用实现,对于消息可靠性和可用性而言也能够追溯到消息中间件背后的一致性协议。对于 Kafka 而言,其采用的是相似 PacificA 的一致性协议,经过 ISR(In-Sync-Replica)来保证多副本之间的同步,而且支持强一致性语义(经过 acks 实现)。对应的 RabbitMQ 是经过镜像环形队列实现多副本及强一致性语义的。多副本能够保证在 master 节点宕机异常以后能够提高 slave 做为新的 master 而继续提供服务来保障可用性。Kafka 设计之初是为日志处理而生,给人们留下了数据可靠性要求不高的不良印象,可是随着版本的升级优化,其可靠性获得极大的加强,详细能够参考 KIP101。就目前而言,在金融支付领域使用 RabbitMQ 居多,而在日志处理、大数据等方面 Kafka 使用居多,随着 RabbitMQ 性能的不断提高和 Kafka 可靠性的进一步加强,相信彼此都能在之前不擅长的领域分得一杯羹。

同步刷盘是加强一个组件可靠性的有效方式,消息中间件也不例外,Kafka 和 RabbitMQ 均可以支持同步刷盘,可是笔者对同步刷盘有必定的疑问:绝大多数情景下,一个组件的可靠性不该该由同步刷盘这种极其损耗性能的操做来保障,而是采用多副本的机制来保证。

这里还要说起的一个方面是扩展能力,这里我狭隘地将此概括到可用性这一维度,消息中间件的扩展能力可以加强其用可用能力及范围,好比前面提到的 RabbitMQ 支持多种消息协议,这个就是基于其插件化的扩展实现。还有从集群部署上来说,归功于 Kafka 的水平扩展能力,其基本上能够达到线性容量提高的水平,在 LinkedIn 实践介绍中就说起了有部署超过千台设备的 Kafka 集群。

具体技术选型指标4:运维管理

在消息中间件的使用过程当中不免会出现各式各样的异常状况,有客户端的,也有服务端的,那么怎样及时有效的进行监测及修复。业务线流量有峰值又低谷,尤为是电商领域,那么怎样前进行有效的容量评估,尤为是大促期间?脚踢电源、网线被挖等事件层出不穷,如何有效的作好异地多活?这些都离不开消息中间件的衍生产品——运维管理。

运维管理也能够进行进一步的细分,好比:申请、审核、监控、告警、管理、容灾、部署等。

申请、审核很好理解,在源头对资源进行管控,既能够进行有效校订应用方的使用规范,配和监控也能够作好流量统计与流量评估工做,通常申请、审核与公司内部系统交融性较大,不适合使用开源类的产品。

监控、告警也比较好理解,对消息中间件的使用进行全方位的监控,便可觉得系统提供基准数据,也能够在检测到异常的状况配合告警,以便运维、开发人员的迅速介入。除了通常的监控项(好比硬件、GC 等)以外,对于消息中间件还须要关注端到端时延、消息审计、消息堆积等方面。对于 RabbitMQ 而言,最正统的监控管理工具莫过于 rabbitmq_management 插件了,可是社区内还有 AppDynamics, Collectd, DataDog, Ganglia, Munin, Nagios, New Relic, Prometheus, Zenoss 等多种优秀的产品。Kafka 在此方面也绝不逊色,好比:Kafka Manager, Kafka Monitor, Kafka Offset Monitor, Burrow, Chaperone, Confluent Control Center 等产品,尤为是 Cruise 还能够提供自动化运维的功能。

无论是扩容、降级、版本升级、集群节点部署、仍是故障处理都离不开管理工具的应用,一个配套完备的管理工具集能够在遇到变动时作到事半功倍。故障可大可小,通常是一些应用异常,也能够是机器掉电、网络异常、磁盘损坏等单机故障,这些故障单机房内的多副本足以应付。若是是机房故障就要涉及异地容灾了,关键点在于如何有效的进行数据复制,对于 Kafka 而言,能够参考 MirrorMarker、uReplicator 等产品,而 RabbitMQ 能够参考 Federation 和 Shovel。

具体技术选型指标5:社区力度及生态发展

对于目前流行的编程语言而言,如 Java、Python,若是你在使用过程当中遇到了一些异常,基本上能够经过搜索引擎的帮助来获得解决,由于一个产品用的人越多,踩过的坑也就越多,对应的解决方案也就越多。对于消息中间件也一样适用,若是你选择了一种“生僻”的消息中间件,可能在某些方面运用的驾轻就熟,可是版本更新缓慢、遇到棘手问题也难以获得社区的支持而越陷越深;相反若是你选择了一种“流行”的消息中间件,其更新力度大,不只能够迅速的弥补以前的不足,并且也能顺应技术的快速发展来变动一些新的功能,这样可让你以“站在巨人的肩膀上”。在运维管理维度咱们说起了 Kafka 和 RabbitMQ 都有一系列开源的监控管理产品,这些正是得益于其社区及生态的迅猛发展。

 

消息中间件选型还有一个考量标准就是尽可能贴合团队自身的技术栈体系,虽说没有蹩脚的消息中间件只有蹩脚的程序员,可是让一个 C 栈的团队去深挖 PhxQueue 总比去深挖 Scala 编写的 Kafka 要容易的多。

 

消息中间件选型切忌一味的追求性能或者功能,性能能够优化,功能能够二次开发。若是要在功能和性能方面作一个抉择的话,那么首选性能,由于整体上来讲性能优化的空间没有功能扩展的空间大。然而对于长期发展而言,生态又比性能以及功能都要重要。

 

消息中间件大道至简:一发一存一消费,没有最好的消息中间件,只有最合适的消息中间件

 

 <http://www.52im.net/thread-1647-1-1.html

相关文章
相关标签/搜索