mq消息中间件


教学设计 2019-08-13 17:29:59 教学设计
[摘要]mq消息中间件篇一:消息中间件 MQ 企业级方案设计,第 1 部分: 异步通信与负载均衡引言 要了解关于消息中间件 MQ 企业级方案设计的系列文章,请访问以下链接:消息中间件 MQ 企业级方案设计,第 1 部分消息中间件 MQ 企业级方案设计,第 2 部分消息中间件 MQ 企业级方案设计,第

【www.shanpow.com--教学设计】

mq消息中间件篇一:消息中间件 MQ 企业级方案设计,第 1 部分: 异步通信与负载均衡


引言
要了解关于消息中间件 MQ 企业级方案设计的系列文章,请访问以下链接:
消息中间件 MQ 企业级方案设计,第 1 部分
消息中间件 MQ 企业级方案设计,第 2 部分
消息中间件 MQ 企业级方案设计,第 3 部分
Websphere MQ 是 IBM 功能强大的消息传送中间件产品,它以其成熟的技术和世界领先的产品向我们提供了的功能丰富、可靠易用的异构平台间实现可靠信息传递的成熟解决方案。使用 MQ 消息传递产品可以帮助业务应用在不同种类平台上交换信息,以消息的方式接收、发送数据,从而实现企业应用集成。MQ 屏蔽了异构软硬件平台和网络协议的复杂性,确保“消息到达并且仅到达一次”的可靠的消息传递,满足高可靠性的、高性能的、安全可靠的稳定信息数据传输要求,并具有开放性、扩展性、先进性、安全性、可管理性和易于维护开发等特性。依靠这些优势,MQ 在消息类中间件市场上占有统治地位,已经成为事实上的行业标准,在企业的各类应用中承担了可靠的信息数据传输的基础支撑。MQ 是为能够支撑大型企业的海量信息传输而设计的,它设计了很多应用特性,为企业级应用提供支持,这些特性分散在系统设计和应用编程的各种细节之处。本系列以使用 IBM 大型机服务器的客户为主要对象,对异步通信与同步通信、MQ 高可用性及负载均衡方案、MQ 的安全性实现、MQ 与传统 CICS 应用的连接、使用 MQ 实现 SOA 服务、MQ 应用性能监控和企业级应用设计构架等几个方面探讨如何应用 MQ 的特性实现企业级应用的业务需求。本文是本系列的第 1 部分,将为大家介绍异步通信与同步通信的特点与设计考虑以及 MQ 高可用性及负载均衡方案。
回页首
异步通信与同步通信
异步通信与同步通信的特点
MQ 在支持同步通讯的同时,提供了基于消息队列存储 - 转发机制的异步通讯模式,应用程序只需将消息交给 MQ,就由 MQ 负责将消息安全、可靠地发送出去,不再需要应用和人工的干预,真正实现了数据传输自动化,这一特点能够使应用程序独立于通信对方和网络的可用性。与我们常见的同步通信相比,异步通信模式有以下特点:
通信的达成只依赖于发送方和消息中间件,接收方以及网络的意外情况不造成影响。
因为不必实现同步握手,异步通信通常效率更高。
因为不必等待响应,异步通信倾向于实现更短的交易处理,节省系统资源占用。
异步通信有利于提高系统并发度,提高系统吞吐能力。
异步通信有利于实现松散耦合的系统结构。
与异步通信相比,同步通信想法更为简单而且更容易实现――发起方在系统中等待直到对方响应,这样可以避免复杂的发送 / 确认 / 重传机制的设计,但同时也造成了低效率和对资源占用大的缺点,同步通信目前是一种常见的廉价通信实现方式。
需要说明的是这里谈论的同步 / 异步是底层消息传输的模式,与其最终提供的服务模式无关:同步业务服务可以通过同步通信实现,也可以通过异步通信实现。比如我们常见的电话业务,一般我们都认为是一种同步的服务,但电信公司实际实施时,如果是通过交换机,在通话双方之间建立一个电路连接,那就是一种同步通信实现;如果电信公司采用的是 IP 电话,通过网络把声音打成若干数据包在 Internet 上发送,在收话方没有感觉到的时间内再按顺序组合把语音还原出来,那就是使用的异步底层通信实现。我们进行应用方案设计时要充分意识到两种通信模式的特点,考虑各种选择的可能性和优劣。
异步通信实现同步应用设计
由于同步 / 异步通信有各自的特点,所以通过异步通信来实现同步应用时,有一些特殊的方法需要考虑。异步通信基础上实现同步应用,是通过若干异步消息分段实现的,以最简单的双方模式为例,A 发送给 B 一个异步消息,B 接收后完成特定处理,再返回给 B 一个异步消息,如果这个处理过程足够快,就能够实现一个请求 / 应答模式的同步应用。这种模式下,应用中 UOW 的范围,和同步应用下是有很大不同的,应用设计中要充分考虑到这种区别。
在同步模式下,在 A 和 B 的所有操作都可以放在一个 UOW 中,通过两阶段提交协议实现数据一致;在异步模式,应用会分成几个 UOW,第一个是应用程序在本地队列管理器中的操作,第二个是两个队列管理器间的数据传输,这个 UOW 是系统完成的,对于应用是透明的,第三个 UOW 是远程应用在远程队列管理器中的操作。应用设计时要充分意识到这些区别。
由于交易一致性控制,一个 MQ 应用中在队列中进行的改变,只在它 COMMIT 后,其他应用程序才能看到,所以在进行请求 / 应答模式的 MQ 应用程序中,请求程序发送请求消息后,要在适当的位置下 COMMIT,完成这个 UOW,然后在到应答队列里去等待对方完成 UOW 后的返回。应答程序也要与请求程序类似,也要合理地控制 UOW 的范围,使得返回消息能够恰当地被请求程序得到。
在使用 MQ 进行要求同步通讯的程序设计时,会碰到原来可能会做单一 UOW 的应用,在 MQ 下的异步应用设计下要划分成若干个 UOW,这就涉及到如何在多 UOW 下保证数据整体的一致性。这种需求,一般可以通过合理的冲正设计来实现。
MQ Server 与 Client
MQ 产品分为 Server 和 Client 两种版本,在 MQ Server 的运行环境下,有队列管理器、队列、消息通道等对象,它提供全面的消息服务;MQ Client 本身没有队列管理器、队列等对象,它通过 MQI 通道与服务器之间建立通讯,并将消息从客户端发往服务器端的队列,或从 Server 端的队列中取得消息,其他功能也比 Server 有限。MQ Client 与 Server 之间的通信是同步模式完成的,它必须在 Server 正在工作并且可以通过网络访问的情况下才能完成任务。MQ Client 通常在有大量末端环境的应用系统中采用,可以通过这种方式来节省成本,但要求在 Client 到 Server 之间要有比较可靠的网络连接。
回页首
MQ 高可用性及负载均衡方案
大型企业应用方案,在功能性要求之外系统高可靠性能力与负载均衡能力是一个十分重要的衡量指标。MQ 在这方案提供了很强的特性,主要通过两种主要技术实现:MQ Cluster 技术和 Queue Sharing Group 技术。Cluster 技术可以在各种系统平台上甚至跨平台实施,能够提供基本的高可用性能力,Queue Sharing Group 只能在 IBM System z 主机平台上实现,能够提供最高级的高可用性能力。
MQ Cluster 方案
MQ Cluster 结构与特点
使用 Queue Manager Cluster 技术,可以把安装在不同平台(如 AIX,LINUX,WINDOW,z/OS)上的若干个 Queue Manager 设计为一个集群,每个 Queue Manager 都创建成集群中的一员。集群中有一个或多个 Queue Manager 可以定义成拥有整个集群的对象定义信息,称作 Repository queue manager。当用户在集群中创建一个接收通道或队列时,系统会自动在其他队列管理器中创建相应的发送通道和远程队列定义。不论整个集群中有多少 Queue Manager,每个 Queue Manager 只要建立一个接收通道,和一个指向 Repository queue manager 的发送通道就可以完成消息连通,而不必要针对每个 queue manager 分别定义通道;同时每个 Queue Manager 也不必要定义远程所有用到的远程 Queue.
图1 MQ Cluster 集群
通过 Cluster 技术,可以有效地减少系统的管理工作,更快地建立应用同时可以提高系统的可用性并可以在集群 MQ 管理器间实现负载均衡。
减少系统的管理工作主要体现在 :
不论连接多少远程队列管理器,只要建一个集群发送通道和一个集群接收通道,不必为每个管理器分别建立通道
每个队列管理器只要建立一个 transmission queues。
不必一一定义远程队列,可直接使用
使用 Cluster 技术提高系统的可用性和实现负载均衡,是通过在 Cluster 内的不同 QMGR 上建立同名的 Queue(同一个 Queue 的多个实例)来实现的。每个 Queue 的实例都能作为消息的目的地,MQ 能够在依照一定的算法决定实际消息应当传给哪个 QMGR。这样当集群里某个 QMGR 失效时,消息会自动路由到其他活动的 QMGR 管理的实例上去。
典型部署模式
在实际应用 Cluster 技术时,一般采取如下的部署方案:
图2 MQ Cluster 的典型部署模式
在 Cluster 中首先设计一台 MQ 服务器作为整个 Cluster 的网关,作为对外的连接点,它本地并不定义任何输入(Inbound)队列(如上例中的 Q1),只定义输出(Outbound)队列(如上例中的 Q2)。另外设置若干消息处理服务器,其中定义本地的输入队列,同时有消息处理程序在运行。在外部交易进入 Cluster 时首先发送到网关机上,由网关动态地发送到 Cluster 里定义了输入队列的 MQ 服务器上去。MQ 网关可以根据设置,按照轮循或权重的方式对进入的消息进行分发,还可以通过出口程序(User Exit)实现更加复杂的分发机制。
在每个消息处理服务器都部署有完全相同的应用处理程序,它们读取输入队列里的消息,经过处理后把结果写入输出队列。输出队列只定义在 MQ 网关机器上,任何消息处理服务器写出的消息都回最终传送到网关上。前台程序连接网关,读取返回结果。
为了获得更高可用性,这个方案中有两点需要注意:1. 可以看到 MQ 网关是个单点隐患,为了更高可用性,要使用 HACMP 等方案实现备份。2. 如果消息处理服务器上的应用程序意外停止运行,数据会在队列中堆积起来,为了避免这种情况,需要自动脚本在应用程序停止时自动把 MQ 停止,这样后来的消息会发给其他服务器处理。
网络层负载均衡器与 MQ
一些企业中,经常使用 F5 之只类的网络层负载均衡器来实现一种高可靠性 / 负载均衡解决方案。很多应用可以依靠 F5 实现的动态 IP 地址功能,在不改变应用程序的情况下实现高可用性,这为无状态的网络应用提供了方便的均衡手段。但是 MQ 产品为实现消息到并且只到一次,在收发双方的发送通道和接收通道上要传递记数和确认信息,这样以来发送和接收方必须有固定的一对一关系,如果在中间网络上配置了网络层的负载均衡器,由于它不知道这种机制的存在,必然造成通信的错乱,所以在使用 MQ 的网络环境中不能够同时使用网络层的负载均衡设备。
主机 MQ 特有高可用性技术 -Queue Sharing Group 设计
Queue-Sharing Group 技术介绍
Shared Queue Group 是 MQ 依托 System z 主机的 Parallel Sysplex 技术而实现的高级特性。Shared queue 是一种本地队列,shared queue 里存储的数据可以被同一个 Sysplex 里的若干个 QMGR 共同访问。能够访问同一个 shared queue 的所有 QMGR 称为一个 queue-sharing group,它们可以访问同一组 shared queues。 Shared queue 的数据存储在 Coupling Facility 的 list structures 里面,一个 Group 里的所有队列管理器都能够从这个队列里读取数据和发送数据。
图3MQ Queue Share Group
Shared queue 的定义被所有 QMGR 共享,共享的队列定义是存放在 DB2 的表里,在一个群里,队列只要定义一次,就能被所有的 QMGR 共享。Queue-sharing group 里的每个 QMGR 都有与一个 DB2 系统相连,这些 DB2 系统必须在一个 data-sharing group 里,这样 QMGR 才能够访问相同的共享队列定义。
在主机上使用 Queue Share Group 技术,结合 Sysplex 提供的系统功能(如 SYSPLEX Distributor 和 VTAM generic resources),MQ 除了可以实现应用处理上的高可用性,还能够提供网络接入和送出的高可用性,这是通过 MQ 的 Shared channel 来实现的。
图4 MQ 共享通道
共享的接入通道 : Queue-sharing group 里的每个 MQ Server 的 channel initiator 都在同一个 IP 端口监听消息,这个端口通过 Sysplex 提供的网络技术对外做成一个 generic port。这样分布式系统 MQ Channel 的连接请求会被分发到任意一个 MQ Server 上,只要 Group 里还有一个 Server 能够响应,就能够完成消息向 Shared Queue 里的发送。
共享的外传通道 :如果一个发送通道的 transmission queue 定义为共享的 Shared Queue,那么这个通道就是共享的外传通道。Group 里的任意一个 QueueManger 都可以从共享的 transmission queue 里取得数据向外传输,这样只要还有一个 QM 有响应,这个通道对外就是畅通的。
Shared queue 技术使 MQ 在应用上具有以下优点:
Scalability
应用处理能力能够很方便地进行扩展,只要新增一个 QMGR,甚至新增一个 z/OS image 并在上面建立 QMGR 和应用程序,就能很好地扩大系统处理能力。
Availability
多个 QMGR 可以访问同一个 Queue,单个 QMGR 的故障不影响 Shared queue 的应用。MQ 通过 peer recovery 技术,可以监控 QMGR 的非正常中断,能够自动回滚未完成的 ULW。
Workload balance
利用 SYSPLEX 的负载均衡功能,可以在多个 QMGR 间平衡处理量。
Queue Share Group 技术的优势
Cluster 技术和 Share Queue 技术为实现可靠性、扩展性和均衡,使用的基本手段是不同的:
Queue Manager Cluster
Queue Manager Cluster 使用的是同名队列的多个实例,就是在 Cluster 里的多个 QMGR 上建立相同的 Queue。进入这个队列的数据会转发给某个 QMGR,一旦数据进入这个 QMGR,就只能由这个 QMGR 访问。
Queue-Sharing Group
Queue-Sharing Group 使用的是一个共享的队列,队列的数据存储只有一份,可以由多个 QMGR 共同访问。
抛开 zSeries 对其他开放平台的系统优势不谈,由于这个基本手段本质的不同,使得两种技术提供的服务水平有很大不同:
Cluster 只在消息进入时实现高可用性,一旦消息进入某个 QMGR,它就只能由那个 QMGR 处理,如果在消息被处理完之前,系统发生故障,已经进入这个 QMGR 的数据将不能被处理。而使用 Shared queue 时,一个 QMGR 失败不会影响队列里的数据。
Queue Manager Cluster 时一旦数据进入某个 QMGR,就只能被这个 QMGR 访问,如果某个系统上的 QMGR 正常,但处理 MQ 消息的应用程序发生故障停止运行,消息还会继续发送到这个 QMGR 里去,但这些消息就会积压在这里不会得到处理。在 Shared queue 时,由于 QMGR 使用的是同一个队列,如果某个 QMGR 后面的应用程序停止工作,消息会被其他 QMGR 后面的应用程序处理,不会对整个应用造成任何影响。
Share Queue 是在 Work Load Manager 协调下完成负载均衡的,其负载均衡能力比 Cluster 内带的逻辑要更加强大。Cluster 只能根据消息进入集群时的负载情形转发消息,而 Share Queue 能在消息处理过程中动态地平衡负载。
考虑消息进入时的情况,对于 Cluster,发送方必须指定发送到 Cluster 里做 Gateway 的机器的 IP 地址上,一旦这台机器失效,虽然这个 Queue 的其他 QMGR 还在,消息却不能进入 Cluster,存在单点故障隐患;对于 Share Queue,通过 SYSPLEX Distributor 等技术,发送到特定 IP 地址的数据,可以被路由到任何一台机器,单个机器失效,不会造成影响。
回页首
结束语
本文是本系列的第 1 部分,为大家介绍了异步通信与同步通信的特点与设计考虑以及 MQ 高可用性及负载均衡方案,下面几节将继续为大家介绍 MQ 的安全性实现 ,MQ 与传统 CICS 应用的连接 , 使用 MQ 实现 SOA 服务 ,MQ 应用监控以及企业级应用设计构架技术方案。

mq消息中间件篇二:消息中间件选型分析


消息中间件选型分析
    ——从Kafka与RabbitMQ的对比来看全局
有很多网友留言:公司要做消息中间件选型,该如何选?你觉得哪个比较好?消息选型的确是一个大论题,实则说来话长的事情又如何长话短说。对此笔者专门撰稿一篇内功心法:如何看待消息中间件的选型,不过这篇只表其意未表其行,为了弥补这种缺陷,笔者最近特意重新撰稿一篇,以供参考。温馨提示:本文一万多字,建议先马(关注)后看。
一、前言
消息队列中间件(简称消息中间件)是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下提供应用解耦、弹性伸缩、冗余存储、流量削峰、异步通信、数据同步等等功能,其作为分布式系统架构中的一个重要组件,有着举足轻重的地位。
目前开源的消息中间件可谓是琳琅满目,能让大家耳熟能详的就有很多,比如ActiveMQ、RabbitMQ、Kafka、RocketMQ、ZeroMQ等。不管选择其中的哪一款,都会有用的不趁手的地方,毕竟不是为你量身定制的。有些大厂在长期的使用过程中积累了一定的经验,其消息队列的使用场景也相对稳定固化,或者目前市面上的消息中间件无法满足自身需求,并且也具备足够的精力和人力而选择自研来为自己量身打造一款消息中间件。但是绝大多数公司还是不会选择重复造轮子,那么选择一款合适自己的消息中间件显得尤为重要。就算是前者,那么在自研出稳定且可靠的相关产品之前还是会经历这样一个选型过程。
在整体架构中引入消息中间件,势必要考虑很多因素,比如成本及收益问题,怎么样才能达到最优的性价比?虽然消息中间件种类繁多,但是各自都有各自的侧重点,选择合适自己、扬长避短无疑是最好的方式。如果你对此感到无所适从,本文或许可以参考一二。
二、各类消息队列简述
ActiveMQ是Apache出品的、采用Java语言编写的完全基于JMS1.1规范的面向消息的中间件,为应用程序提供高效的、可扩展的、稳定的和安全的企业级消息通信。不过由于历史原因包袱太重,目前市场份额没有后面三种消息中间件多,其最新架构被命名为Apollo,号称下一代ActiveMQ,有兴趣的同学可行了解。
RabbitMQ是采用Erlang语言实现的AMQP协议的消息中间件,最初起源于金融系统,用于在分布式系统中存储转发消息。RabbitMQ发展到今天,被越来越多的人认可,这和它在可靠性、可用性、扩展性、功能丰富等方面的卓越表现是分不开的。
Kafka起初是由LinkedIn公司采用Scala语言开发的一个分布式、多分区、多副本且基于zookeeper协调的分布式消息系统,现已捐献给Apache基金会。它是一种高吞吐量的分布式发布订阅消息系统,以可水平扩展和高吞吐率而被广泛使用。目前越来越多的开源分布式处理系统如Cloudera、Apache Storm、Spark、Flink等都支持与Kafka集成。
RocketMQ是阿里开源的消息中间件,目前已经捐献个Apache基金会,它是由Java语言开发的,具备高吞吐量、高可用性、适合大规模分布式系统应用等特点,经历过双11的洗礼,实力不容小觑。
ZeroMQ号称史上最快的消息队列,基于C语言开发。ZeroMQ是一个消息处理队列库,可在多线程、多内核和主机之间弹性伸缩,虽然大多数时候我们习惯将其归入消息队列家族之中,但是其和前面的几款有着本质的区别,ZeroMQ本身就不是一个消息队列服务器,更像是一组底层网络通讯库,对原有的Socket API上加上一层封装而已。
目前市面上的消息中间件还有很多,比如腾讯系的PhxQueue、CMQ、CKafka,又比如基于Go语言的NSQ,有时人们也把类似Redis的产品也看做消息中间件的一种,当然它们都很优秀,但是本文篇幅限制无法穷极所有,下面会针对性的挑选RabbitMQ和Kafka两款典型的消息中间件来做分析,力求站在一个公平公正的立场来阐述消息中间件选型中的各个要点。
三、选型要点概述
衡量一款消息中间件是否符合需求需要从多个维度进行考察,首要的就是功能维度,这个直接决定了你能否最大程度上的实现开箱即用,进而缩短项目周期、降低成本等。如果一款消息中间件的功能达不到想要的功能,那么就需要进行二次开发,这样会增加项目的技术难度、复杂度以及增大项目周期等。
1. 功能维度
功能维度又可以划分个多个子维度,大致可以分为以下这些:
优先级队列
优先级队列不同于先进先出队列,优先级高的消息具备优先被消费的特权,这样可以为下游提供不同消息级别的保证。不过这个优先级也是需要有一个前提的:如果消费者的消费速度大于生产者的速度,并且消息中间件服务器(一般简单的称之为Broker)中没有消息堆积,那么对于发送的消息设置优先级也就没有什么实质性的意义了,因为生产者刚发送完一条消息就被消费者消费了,那么就相当于Broker中至多只有一条消息,对于单条消息来说优先级是没有什么意义的。
延迟队列
当你在网上购物的时候是否会遇到这样的提示:“三十分钟之内未付款,订单自动取消”?这个是延迟队列的一种典型应用场景。延迟队列存储的是对应的延迟消息,所谓“延迟消息”是指当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。延迟队列一般分为两种:基于消息的延迟和基于队列的延迟。基于消息的延迟是指为每条消息设置不同的延迟时间,那么每当队列中有新消息进入的时候就会重新根据延迟时间排序,当然这也会对性能造成极大的影响。实际应用中大多采用基于队列的延迟,设置不同延迟级别的队列,比如5s、10s、30s、1min、5mins、10mins等,每个队列中消息的延迟时间都是相同的,这样免去了延迟排序所要承受的性能之苦,通过一定的扫描策略(比如定时)即可投递超时的消息。
死信队列
由于某些原因消息无法被正确的投递,为了确保消息不会被无故的丢弃,一般将其置于一个特殊角色的队列,这个队列一般称之为死信队列。与此对应的还有一个“回退队列”的概念,试想如果消费者在消费时发生了异常,那么就不会对这一次消费进行确认(Ack),进而发生回滚消息的操作之后消息始终会放在队列的顶部,然后不断被处理和回滚,导致队列陷入死循环。为了解决这个问题,可以为每个队列设置一个回退队列,它和死信队列都是为异常的处理提供的一种机制保障。实际情况下,回退队列的角色可以由死信队列和重试队列来扮演。
重试队列
重试队列其实可以看成是一种回退队列,具体指消费端消费消息失败时,为防止消息无故丢失而重新将消息回滚到Broker中。与回退队列不同的是重试队列一般分成多个重试等级,每个重试等级一般也会设置重新投递延时,重试次数越多投递延时就越大。举个例子:消息第一次消费失败入重试队列Q1,Q1的重新投递延迟为5s,在5s过后重新投递该消息;如果消息再次消费失败则入重试队列Q2,Q2的重新投递延迟为10s,在10s过后再次投递该消息。以此类推,重试越多次重新投递的时间就越久,为此需要设置一个上限,超过投递次数就入死信队列。重试队列与延迟队列有相同的地方,都是需要设置延迟级别,它们彼此的区别是:延迟队列动作由内部触发,重试队列动作由外部消费端触发;延迟队列作用一次,而重试队列的作用范围会向后传递。
消费模式
消费模式分为推(push)模式和拉(pull)模式。推模式是指由Broker主动推送消息至消费端,实时性较好,不过需要一定的流制机制来确保服务端推送过来的消息不会压垮消费端。而拉模式是指消费端主动向Broker端请求拉取(一般是定时或者定量)消息,实时性较推模式差,但是可以根据自身的处理能力而控制拉取的消息量。
广播消费
消息一般有两种传递模式:点对点(P2P,Point-to-Point)模式和发布/订阅(Pub/Sub)模式。对于点对点的模式而言,消息被消费以后,队列中不会再存储,所以消息消费者不可能消费到已经被消费的消息。虽然队列可以支持多个消费者,但是一条消息只会被一个消费者消费。发布订阅模式定义了如何向一个内容节点发布和订阅消息,这个内容节点称为主题(topic),主题可以认为是消息传递的中介,消息发布者将消息发布到某个主题,而消息订阅者则从主题中订阅消息。主题使得消息的订阅者与消息的发布者互相保持独立,不需要进行接触即可保证消息的传递,发布/订阅模式在消息的一对多广播时采用。RabbitMQ是一种典型的点对点模式,而Kafka是一种典型的发布订阅模式。但是RabbitMQ中可以通过设置交换器类型来实现发布订阅模式而达到广播消费的效果,Kafka中也能以点对点的形式消费,你完全可以把其消费组(consumer group)的概念看成是队列的概念。不过对比来说,Kafka中因为有了消息回溯功能的存在,对于广播消费的力度支持比RabbitMQ的要强。
消息回溯
一般消息在消费完成之后就被处理了,之后再也不能消费到该条消息。消息回溯正好相反,是指消息在消费完成之后,还能消费到之前被消费掉的消息。对于消息而言,经常面临的问题是“消息丢失”,至于是真正由于消息中间件的缺陷丢失还是由于使用方的误用而丢失一般很难追查,如果消息中间件本身具备消息回溯功能的话,可以通过回溯消费复现“丢失的”消息进而查出问题的源头之所在。消息回溯的作用远不止与此,比如还有索引恢复、本地缓存重建,有些业务补偿方案也可以采用回溯的方式来实现。
消息堆积+持久化
流量削峰是消息中间件的一个非常重要的功能,而这个功能其实得益于其消息堆积能力。从某种意义上来讲,如果一个消息中间件不具备消息堆积的能力,那么就不能把它看做是一个合格的消息中间件。消息堆积分内存式堆积和磁盘式堆积。RabbitMQ是典型的内存式堆积,但这并非绝对,在某些条件触发后会有换页动作来将内存中的消息换页到磁盘(换页动作会影响吞吐),或者直接使用惰性队列来将消息直接持久化至磁盘中。Kafka是一种典型的磁盘式堆积,所有的消息都存储在磁盘中。一般来说,磁盘的容量会比内存的容量要大得多,对于磁盘式的堆积其堆积能力就是整个磁盘的大小。从另外一个角度讲,消息堆积也为消息中间件提供了冗余存储的功能。援引纽约时报的案例(https://www.confluent.io/blog/publishing-apache-kafka-new-york-times/),其直接将Kafka用作存储系统。
消息追踪
对于分布式架构系统中的链路追踪(trace)而言,大家一定不会陌生。对于消息中间件而言,消息的链路追踪(以下简称消息追踪)同样重要。对于消息追踪最通俗的理解就是要知道消息从哪来,存在哪里以及发往哪里去。基于此功能下,我们可以对发送或者消费完的消息进行链路追踪服务,进而可以进行问题的快速定位与排查。
消息过滤
消息过滤是指按照既定的过滤规则为下游用户提供指定类别的消息。就以kafka而言,完全可以将不同类别的消息发送至不同的topic中,由此可以实现某种意义的消息过滤,或者Kafka还可以根据分区对同一个topic中的消息进行分类。不过更加严格意义上的消息过滤应该是对既定的消息采取一定的方式按照一定的过滤规则进行过滤。同样以Kafka为例,可以通过客户端提供的ConsumerInterceptor接口或者Kafka Stream的filter功能进行消息过滤。
多租户
也可以称为多重租赁技术,是一种软件架构技术,主要用来实现多用户的环境下公用相同的系统或程序组件,并且仍可以确保各用户间数据的隔离性。RabbitMQ就能够支持多租户技术,每一个租户表示为一个vhost,其本质上是一个独立的小型RabbitMQ服务器,又有自己独立的队列、交换器及绑定关系等,并且它拥有自己独立的权限。vhost就像是物理机中的虚拟机一样,它们在各个实例间提供逻辑上的分离,为不同程序安全保密地允许数据,它既能将同一个RabbitMQ中的众多客户区分开,又可以避免队列和交换器等命名冲突。
多协议支持
消息是信息的载体,为了让生产者和消费者都能理解所承载的信息(生产者需要知道如何构造消息,消费者需要知道如何解析消息),它们就需要按照一种统一的格式描述消息,这种统一的格式称之为消息协议。有效的消息一定具有某种格式,而没有格式的消息是没有意义的。一般消息层面的协议有AMQP、MQTT、STOMP、XMPP等(消息领域中的JMS更多的是一个规范而不是一个协议),支持的协议越多其应用范围就会越广,通用性越强,比如RabbitMQ能够支持MQTT协议就让其在物联网应用中获得一席之地。还有的消息中间件是基于其本身的私有协议运转的,典型的如Kafka。
跨语言支持
对很多公司而言,其技术栈体系中会有多种编程语言,如C/C++、JAVA、Go、PHP等,消息中间件本身具备应用解耦的特性,如果能够进一步的支持多客户端语言,那么就可以将此特性的效能扩大。跨语言的支持力度也可以从侧面反映出一个消息中间件的流行程度。
流量控制
流量控制(flow control)针对的是发送方和接收方速度不匹配的问题,提供一种速度匹配服务抑制发送速率使接收方应用程序的读取速率与之相适应。通常的流控方法有Stop-and-wait、滑动窗口以及令牌桶等。
消息顺序性
顾名思义,消息顺序性是指保证消息有序。这个功能有个很常见的应用场景就是CDC(Change Data Chapture),以MySQL为例,如果其传输的binlog的顺序出错,比如原本是先对一条数据加1,然后再乘以2,发送错序之后就变成了先乘以2后加1了,造成了数据不一致。
安全机制
在Kafka 0.9版本之后就开始增加了身份认证和权限控制两种安全机制。身份认证是指客户端与服务端连接进行身份认证,包括客户端与Broker之间、Broker与Broker之间、Broker与ZooKeeper之间的连接认证,目前支持SSL、SASL等认证机制。权限控制是指对客户端的读写操作进行权限控制,包括对消息或Kafka集群操作权限控制。权限控制是可插拔的,并支持与外部的授权服务进行集成。对于RabbitMQ而言,其同样提供身份认证(TLS/SSL、SASL)和权限控制(读写操作)的安全机制。
消息幂等性
对于确保消息在生产者和消费者之间进行传输而言一般有三种传输保障(delivery guarantee):At most once,至多一次,消息可能丢失,但绝不会重复传输;At least once,至少一次,消息绝不会丢,但是可能会重复;Exactly once,精确一次,每条消息肯定会被传输一次且仅一次。对于大多数消息中间件而言,一般只提供At most once和At least once两种传输保障,对于第三种一般很难做到,由此消息幂等性也很难保证。
Kafka自0.11版本开始引入了幂等性和事务,Kafka的幂等性是指单个生产者对于单分区单会话的幂等,而事务可以保证原子性地写入到多个分区,即写入到多个分区的消息要么全部成功,要么全部回滚,这两个功能加起来可以让Kafka具备EOS(Exactly Once Semantic)的能力。
不过如果要考虑全局的幂等,还需要与从上下游方面综合考虑,即关联业务层面,幂等处理本身也是业务层面所需要考虑的重要议题。以下游消费者层面为例,有可能消费者消费完一条消息之后没有来得及确认消息就发生异常,等到恢复之后又得重新消费原来消费过的那条消息,那么这种类型的消息幂等是无法有消息中间件层面来保证的。如果要保证全局的幂等,需要引入更多的外部资源来保证,比如以订单号作为唯一性标识,并且在下游设置一个去重表。
事务性消息
事务本身是一个并不陌生的词汇,事务是由事务开始(Begin Transaction)和事务结束(End Transaction)之间执行的全体操作组成。支持事务的消息中间件并不在少数,Kafka和RabbitMQ都支持,不过此两者的事务是指生产者发生消息的事务,要么发送成功,要么发送失败。消息中间件可以作为用来实现分布式事务的一种手段,但其本身并不提供全局分布式事务的功能。
下表是对Kafka与RabbitMQ功能的总结性对比及补充说明。
功能项
Kafka(1.1.0版本)
RabbitMQ(3.6.10版本)
优先级队列
不支持
支持。建议优先级大小设置在0-10之间。
延迟队列
不支持
支持
死信队列
不支持
支持
重试队列
不支持
不支持。RabbitMQ中可以参考延迟队列实现一个重试队列,二次封装比较简单。如果要在Kafka中实现重试队列,首先得实现延迟队列的功能,相对比较复杂。
消费模式
拉模式
推模式+拉模式
广播消费
支持。Kafka对于广播消费的支持相对而言更加正统。
支持,但力度较Kafka弱。
消息回溯
支持。Kafka支持按照offset和timestamp两种维度进行消息回溯。
不支持。RabbitMQ中消息一旦被确认消费就会被标记删除。
消息堆积
支持
支持。一般情况下,内存堆积达到特定阈值时会影响其性能,但这不是绝对的。如果考虑到吞吐这因素,Kafka的堆积效率比RabbitMQ总体上要高很多。
持久化
支持
支持
消息追踪
不支持。消息追踪可以通过外部系统来支持,但是支持粒度没有内置的细腻。
支持。RabbitMQ中可以采用Firehose或者rabbitmq_tracing插件实现。不过开启rabbitmq_tracing插件件会大幅影响性能,不建议生产环境开启,反倒是可以使用Firehose与外部链路系统结合提供高细腻度的消息追踪支持。
消息过滤
客户端级别的支持
不支持。但是二次封装一下也非常简单。
多租户
不支持
支持
多协议支持
只支持定义协议,目前几个主流版本间存在兼容性问题。
RabbitMQ本身就是AMQP协议的实现,同时支持MQTT、STOMP等协议。
跨语言支持
采用Scala和Java编写,支持多种语言的客户端。
采用Erlang编写,支持多种语言的客户端。
流量控制
支持client和user级别,通过主动设置可将流控作用于生产者或消费者。
RabbitMQ的流控基于Credit-Based算法,是内部被动触发的保护机制,作用于生产者层面。
消息顺序性
支持单分区(partition)级别的顺序性。
顺序性的条件比较苛刻,需要单线程发送、单线程消费并且不采用延迟队列、优先级队列等一些高级功能,从某种意义上来说不算支持顺序性。
安全机制
(TLS/SSL、SASL)身份认证和(读写)权限控制
与Kafka相似
幂等性
支持单个生产者单分区单会话的幂等性。
不支持
事务性消息
支持
支持
2. 性能
功能维度是消息中间件选型中的一个重要的参考维度,但这并不是唯一的维度。有时候性能比功能还要重要,况且性能和功能很多时候是相悖的,鱼和熊掌不可兼得,Kafka在开启幂等、事务功能的时候会使其性能降低,RabbitMQ在开启rabbitmq_tracing插件的时候也会极大的影响其性能。消息中间件的性能一般是指其吞吐量,虽然从功能维度上来说,RabbitMQ的优势要大于Kafka,但是Kafka的吞吐量要比RabbitMQ高出1至2个数量级,一般RabbitMQ的单机QPS在万级别之内,而Kafka的单机QPS可以维持在十万级别,甚至可以达到百万级。
消息中间件的吞吐量始终会受到硬件层面的限制。就以网卡带宽为例,如果单机单网卡的带宽为1Gbps,如果要达到百万级的吞吐,那么消息体大小不得超过(1Gb/8)/100W,即约等于134B,换句话说如果消息体大小超过134B,那么就不可能达到百万级别的吞吐。这种计算方式同样可以适用于内存和磁盘。
时延作为性能维度的一个重要指标,却往往在消息中间件领域所被忽视,因为一般使用消息中间件的场景对时效性的要求并不是很高,如果要求时效性完全可以采用RPC的方式实现。消息中间件具备消息堆积的能力,消息堆积越大也就意味着端到端的时延也就越长,与此同时延时队列也是某些消息中间件的一大特色。那么为什么还要关注消息中间件的时延问题呢?消息中间件能够解耦系统,对于一个时延较低的消息中间件而言,它可以让上游生产者发送消息之后可以迅速的返回,也可以让消费者更加快速的获取到消息,在没有堆积的情况下可以让整体上下游的应用之间的级联动作更加高效,虽然不建议在时效性很高的场景下使用消息中间件,但是如果所使用的消息中间件的时延方面比较优秀,那么对于整体系统的性能将会是一个不小的提升。
3. 可靠性+可用性
消息丢失是使用消息中间件时所不得不面对的一个同点,其背后消息可靠性也是衡量消息中间件好坏的一个关键因素。尤其是在金融支付领域,消息可靠性尤为重要。然而说到可靠性必然要说到可用性,注意这两者之间的区别,消息中间件的可靠性是指对消息不丢失的保障程度;而消息中间件的可用性是指无故障运行的时间百分比,通常用几个9来衡量。
从狭义的角度来说,分布式系统架构是一致性协议理论的应用实现,对于消息可靠性和可用性而言也可以追溯到消息中间件背后的一致性协议。对于Kafka而言,其采用的是类似PacificA的一致性协议,通过ISR(In-Sync-Replica)来保证多副本之间的同步,并且支持强一致性语义(通过acks实现)。对应的RabbitMQ是通过镜像环形队列实现多副本及强一致性语义的。多副本可以保证在master节点宕机异常之后可以提升slave作为新的master而继续提供服务来保障可用性。Kafka设计之初是为日志处理而生,给人们留下了数据可靠性要求不要的不良印象,但是随着版本的升级优化,其可靠性得到极大的增强,详细可以参考KIP101。就目前而言,在金融支付领域使用RabbitMQ居多,而在日志处理、大数据等方面Kafka使用居多,随着RabbitMQ性能的不断提升和Kafka可靠性的进一步增强,相信彼此都能在以前不擅长的领域分得一杯羹。
同步刷盘是增强一个组件可靠性的有效方式,消息中间件也不例外,Kafka和RabbitMQ都可以支持同步刷盘,但是笔者对同步刷盘有一定的疑问:绝大多数情景下,一个组件的可靠性不应该由同步刷盘这种极其损耗性能的操作来保障,而是采用多副本的机制来保证。
这里还要提及的一个方面是扩展能力,这里我狭隘地将此归纳到可用性这一维度,消息中间件的扩展能力能够增强其用可用能力及范围,比如前面提到的RabbitMQ支持多种消息协议,这个就是基于其插件化的扩展实现。还有从集群部署上来讲,归功于Kafka的水平扩展能力,其基本上可以达到线性容量提升的水平,在LinkedIn实践介绍中就提及了有部署超过千台设备的Kafka集群。
5. 运维管理
在消息中间件的使用过程中难免会出现各式各样的异常情况,有客户端的,也有服务端的,那么怎样及时有效的进行监测及修复。业务线流量有峰值又低谷,尤其是电商领域,那么怎样前进行有效的容量评估,尤其是大促期间?脚踢电源、网线被挖等事件层出不穷,如何有效的做好异地多活?这些都离不开消息中间件的衍生产品——运维管理。
运维管理也可以进行进一步的细分,比如:申请、审核、监控、告警、管理、容灾、部署等。
申请、审核很好理解,在源头对资源进行管控,既可以进行有效校正应用方的使用规范,配和监控也可以做好流量统计与流量评估工作,一般申请、审核与公司内部系统交融性较大,不适合使用开源类的产品。
监控、告警也比较好理解,对消息中间件的使用进行全方位的监控,即可以为系统提供基准数据,也可以在检测到异常的情况配合告警,以便运维、开发人员的迅速介入。除了一般的监控项(比如硬件、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。
6. 社区力度及生态发展
对于目前流行的编程语言而言,如Java、Python,如果你在使用过程中遇到了一些异常,基本上可以通过搜索引擎的帮助来得到解决,因为一个产品用的人越多,踩过的坑也就越多,对应的解决方案也就越多。对于消息中间件也同样适用,如果你选择了一种“生僻”的消息中间件,可能在某些方面运用的得心应手,但是版本更新缓慢、遇到棘手问题也难以得到社区的支持而越陷越深;相反如果你选择了一种“流行”的消息中间件,其更新力度大,不仅可以迅速的弥补之前的不足,而且也能顺应技术的快速发展来变更一些新的功能,这样可以让你以“站在巨人的肩膀上”。在运维管理维度我们提及了Kafka和RabbitMQ都有一系列开源的监控管理产品,这些正是得益于其社区及生态的迅猛发展。
四、消息中间件选型误区探讨
在进行消息中间件选型之前可以先问自己一个问题:是否真的需要一个消息中间件?在搞清楚这个问题之后,还可以继续问自己一个问题:是否需要自己维护一套消息中间件?很多初创型公司为了节省成本会选择直接购买消息中间件有关的云服务,自己只需要关注收发消息即可,其余的都可以外包出去。
很多人面对消息中间件时会有一种自研的冲动,你完全可以对Java中的ArrayBlockingQueue做一个简单的封装,你也可以基于文件、数据库、Redis等底层存储封装而形成一个消息中间件。消息中间件做为一个基础组件并没有想象中的那么简单,其背后还需要配套的管理运维整个生态的产品集。自研还有会交接问题,如果文档不齐全、运作不规范将会带给新人噩梦般的体验。是否真的有自研的必要?如果不是KPI的压迫可以先考虑下这2个问题:1. 目前市面上的消息中间件是否都真的无法满足目前业务需求? 2. 团队是否有足够的能力、人力、财力、精力来支持自研?
很多人在做消息中间件选型时会参考网络上的很多对比类的文章,但是其专业性、严谨性、以及其政治立场问题都有待考证,需要带着怀疑的态度去审视这些文章。比如有些文章会在没有任何限定条件及场景的情况下直接定义某款消息中间件最好,还有些文章没有指明消息中间件版本及测试环境就来做功能和性能对比分析,诸如此类的文章都可以唾弃之。
消息中间件犹如小马过河,选择合适的才最重要,这需要贴合自身的业务需求,技术服务于业务,大体上可以根据上一节所提及的功能、性能等6个维度来一一进行筛选。更深层次的抉择在于你能否掌握其魂,笔者鄙见:RabbitMQ在于routing,而Kafka在于streaming,了解其根本对于自己能够对症下药选择到合适的消息中间件尤为重要。
消息中间件选型切忌一味的追求性能或者功能,性能可以优化,功能可以二次开发。如果要在功能和性能方面做一个抉择的话,那么首选性能,因为总体上来说性能优化的空间没有功能扩展的空间大。然而对于长期发展而言,生态又比性能以及功能都要重要。
很多时候,对于可靠性方面也容易存在一个误区:想要找到一个产品来保证消息的绝对可靠,很不幸的是这世界上没有绝对的东西,只能说尽量趋于完美。想要尽可能的保障消息的可靠性也并非单单只靠消息中间件本身,还要依赖于上下游,需要从生产端、服务端和消费端这3个维度去努力保证,《RabbitMQ消息可靠性分析》这篇文章就从这3个维度去分析了RabbitMQ的可靠性。
消息中间件选型还有一个考量标准就是尽量贴合团队自身的技术栈体系,虽然说没有蹩脚的消息中间件只有蹩脚的程序员,但是让一个C栈的团队去深挖PhxQueue总比去深挖Scala编写的Kafka要容易的多。
五、总结
消息中间件大道至简:一发一存一消费,没有最好的消息中间件,只有最合适的消息中间件。人过留名,雁过留声,路过记得点个赞。  

mq消息中间件篇三:阿里分布式消息中间件RocketMQ的设计思路与技术细节


作者|王小瑞、冯嘉编辑|木环2016年底已捐赠给Apache软件基金会,阿里巴巴开源其自研的第三代分布式消息中间件——RocketMQ在项目思路、技术细节以及未来规划上都有哪些可以供业界参考的经验?为此,InfoQ特意采访了RocketMQ的两位联合创始人。 编者按 2012年,阿里巴巴开源其自研的第三代分布式消息中间件——RocketMQ。经过几年的技术打磨,使用RocketMQ技术的阿里目前可以在双十一当天承受万亿级消息容量。2016年11月,阿里将RocketMQ捐献给Apache软件基金会,正式成为孵化项目。阿里称会将其打造成顶级项目。
这是阿里迈出的一大步,因为加入到开源软件基金会需要经过评审方的考核与观察。坦率而言,业界还对国人的代码开源参与度仍保持着刻板印象;而Apache基金会中的342个项目中,暂时还只有Kylin、CarbonData、Eagle 和 RocketMQ 共计四个中国技术人主导的项目。
2017年2月20日,RocketMQ正式发布4.0版本,专家称新版本适用于电商领域,金融领域,大数据领域,兼有物联网领域的编程模型。
RocketMQ项目背后,究竟有怎样的技术内涵?缘何赢得了基金会的初步认可?入驻基金会可以给技术圈哪些启示?InfoQ带着这样的疑问对两位项目联合创始人进行了专访,内容整理如下。
RocketMQ的由来 谈起RocketMQ的亮点,那不得不先提一下阿里巴巴消息引擎的演进史。阿里中间件消息引擎发展到今日,前前后后经历了三代演进。
第一代,推模式,数据存储采用关系型数据库。在这种模式下,消息具有很低的延迟特性,并且很容易支持分布式事务。尤其在阿里淘宝这种高频交易场景中,具有非常广泛地应用。典型代表包括Notify、Napoli。
第二代,拉模式,自研的专有消息存储。在日志处理方面能够媲美Kafka的吞吐性能,但考虑到淘宝的应用场景,尤其是其交易链路的高可靠需求,消息引擎并没有一味的追求吞吐,而是将稳定可靠放在首位。因为采用了长连接拉模式,在消息的实时方面丝毫不逊推模式。典型代表MetaQ。
第三代,以拉模式为主,兼有推模式的高性能、低延迟消息引擎RocketMQ,在二代功能特性的基础上,为电商金融领域添加了可靠重试、基于文件存储的分布式事务等特性,并做了大量优化。从2012年开始,经历了历次双11核心交易链路检验。目前已经捐赠给Apache基金会。时至今日,RocketMQ很好的服务了阿里集团大大小小上千个应用,在双11当天,更有不可思议的万亿级消息流转,为集团大中台的稳定发挥了举足轻重的作用。
不难看出,RocketMQ其实是伴随着阿里巴巴整个生态的成长,逐渐衍生出来的高性能、低延迟能够同时满足电商领域和金融领域的极尽苛刻场景的消息中间件。
经历双11洗礼的英雄 2016年双十一,阿里巴巴内部的消息中间件全面拥抱RocketMQ的低延迟存储引擎。在备战期间,团队重点做了两件事情,优化慢请求与统一存储引擎;
优化慢请求:这里主要是解决在海量高并发场景下降低慢请求对整个集群带来的抖动,毛刺问题。这是一个极具挑战的技术活,团队同学经过长达1个多月的跟进调优,从双十一的复盘情况来看,99.996%的延迟落在了10ms以内,而99.6%的延迟在1ms以内。优化主要集中在RocketMQ存储层算法优化、JVM与操作系统调优。更多的细节大家可以参考我们之前写的电子书章节《万亿级数据洪峰下的分布式消息引擎》[1]。
统一存储引擎:主要解决的消息引擎的高可用,成本问题。在多代消息引擎共存的前提下,我们对Notify的存储模块进行了全面移植与替换。
基于上述积极的技术准备,在16年双十一期间,阿里集团大约有1.2万亿级的消息流转总量,几乎是15年双十一大促的2倍。峰值期间,消息生产的吞吐在2000 w/s左右,消息消费的吞吐也近乎1500 w/s的量级。整个大促下来,用我们内部的话来说,如丝般顺滑。
RocketMQ的技术概览 在我们看来,它最大的创新点在于能够通过精巧的横向、纵向扩展,不断满足与日俱增的海量消息在高吞吐、高可靠、低延迟方面的要求。
目前RocketMQ主要由NameServer、Broker、Producer以及Consumer四部分构成,如下图所示。
所有的集群都具有水平扩展能力,无单点障碍。
NameServer以轻量级的方式提供服务发现和路由功能,每个NameServer存有全量的路由信息,提供对等的读写服务,支持快速扩缩容。
Broker负责消息存储,以Topic为纬度支持轻量级的队列,单机可以支撑上万队列规模,支持消息推拉模型,具备多副本容错机制(2副本或3副本)、强大的削峰填谷以及上亿级消息堆积能力,同时可严格保证消息的有序性。除此之外,Broker还提供了同城异地容灾能力,丰富的Metrics统计以及告警机制。这些都是传统消息系统无法比拟的。
Producer由用户进行分布式部署,消息由Producer通过多种负载均衡模式发送到Broker集群,发送低延时,支持快速失败。
Consumer也由用户部署,支持PUSH和PULL两种消费模式,支持集群消费和广播消息,提供实时的消息订阅机制,满足大多数消费场景。
与其他消息中间件的对比 1、是不是CS架构?
如果需要做同类产品之间的横向对比,我们优先拿下ZeroMQ,ZeroMQ正如其名0MQ,它更像是一个嵌入式的网络类库,一个专注于transports层的通讯组件,而不是传统意义上的CS架构的MQ。
2、实现的哪种规范 / 协议?
接下来我们来看看RabbitMQ、ActiveMQ、Kafka和RocketMQ之间的一些对比,从设计思路上来看,RabbitMQ是AMQP规范的参考实现,AMQP是一个线路层协议,面面俱到,很系统,也稍显复杂。目前RabbitMQ已经成为OpenStack Iaas平台首选的消息服务,其背后的支持力度不言而喻。
ActiveMQ最初是由红帽子捐赠给Apache的,是JMS规范的参考实现,也是Apache旗下的老牌消息服务引擎。JMS虽说是一个API级别的协议,但其内部还是定义了一些实现约束,不过缺少多语言支撑。ActiveMQ的生态堪称丰富多彩,在该Apache顶级项目下,拥有不少子项目,包括由HornetMQ演变而来的Artemis,基于Scala号称下一代AMQ的Apollo等。
3、适用何类场景?
而Kafka最初被设计用来做日志处理,是一个不折不扣的大数据通道,追求高吞吐,存在丢消息的可能。其背后的研发团队也围绕着Kafka进行了商业包装,目前在一些中小型公司被广泛使用,国内也有不少忠实的拥捧着。
RocketMQ天生为金融互联网领域而生,追求高可靠、高可用、高并发、低延迟,是一个阿里巴巴由内而外成功孕育的典范,除了阿里集团上千个应用外,根据我们不完全统计,国内至少有上百家单位、科研教育机构在使用。关于这几个MQ产品更详细的特性对比,可以参考我们官网上的说明[2]。
三项技术发力点 (一)消息的顺序 不可否认,顺序消息是RocketMQ功能特性上的一个卖点。目前我们做到了全局保序。需要重点说一下,这里的全局是有前提,针对某个唯一标识(能够被Hash成唯一标识),比方说大卖家账号,某类产品的订单等。其技术实现原理也相对比较简单,保证对通道的单一实例操作,如单进程、单线程写,单进程、线程读,像ActiveMQ的Exclusive Consumer也是类似的实现。
不难看出,这种实现方式实际是在吞吐上做出了一定牺牲。另外也带来了另外一个问题 - 热点。如双十一当天,如果使用简单的散列策略,像短期内就交易过亿的天猫商家的消息会发送到一个通道里面,造成单通道,甚至单机的热点问题在最新的RocketMQ版本里,我们将会改进目前的实现,借此改善因为顺序导致的单通道热点问题,这个特性预计今年中旬会发布。
(二)消息的去重 消息领域有一个对消息投递的QoS定义,分为:最多一次(At most once),至少一次(At least once),仅一次( Exactly once)。
几乎所有的MQ产品都声称自己做到了At least once。既然是至少一次,那避免不了消息重复,尤其是在分布式网络环境下,而这个缺憾归根结底也可以看做是TCP协议的一部分,如失败重传。业务上往往对消息重复又很敏感,RocketMQ目前的版本是不支持去重的,我们通常建议用户通过外置全局存储自己做判重处理。在下一代的特性规划里,我们会内置解决方案。先说下业界通用做法,像Artemis,IronMQ等,通过在服务端全局存储判重。这是一个IO敏感的操作,为服务端带来一定的负载。而RocketMQ则希望通过采取二次判重策略,有效降低服务端IO。
(三)分布式的攻坚战 首先明确分布式系统这个概念:分布式系统是由一系列分散自治组件通过互联网并行并发协作,从而组成的一个coherent软件系统。它具备资源共享,并行并发,可靠容错,透明开放等特性。像CAP,BASE,Paxos,事务等一起构成了分布式基础理论。
这里我们再来重温下CAP理论:CAP分别代表一致性(Consistency),可用性(Availability),分区容忍性(Partition tolerance)。一致性,Eric Brewer(CAP理论提出者)用一个服务要么被执行,要么不被执行来定义(原文:A service that is consistent operates fully or not at all)。请注意,这里的一致性是有别于数据库ACID属性中的C,数据库层面的C指的是数据的操作不能破坏数据之间的完整性约束,如外键约束。在分布式环境中,可以把C简单理解为多节点看到的是数据单一或者同一副本。
可用性,意味着服务是可用的(原文:the service is available (to operate fully or not as above))。可用性又可以细分为写可用和读可用。在分布式环境中,往往指的是系统在确定时间内可返回读写操作结果,也即读写均可用。分区容忍性,除了整个网络故障外(如光纤被掘断),其它故障(如丢包、乱序、抖动、甚至是网络分区节点 crash )都不能导致整个系统无法正确响应(原文:No set of failures less than total network failure is allowed to cause the system to respond incorrectly)。
CAP理论可以看做是探索适合不同应用的一致性与可用性平衡问题。
没有分区的情况:可以同时满足C与A,以及完整的ACID事务支持。可以选择牺牲一定的C,获得更好的性能与扩展性。
分区的情况:选择A(集中关注分区的恢复),需要有分区开始前、进行中、恢复后的处理策略,应用合适的补偿处理机制。像RocketMQ这样的分布式消息引擎,更多的追求AP。再强的系统也一定有容量底线,足够的容量是可用性的有效前提。通常情况下,会通过降级、限流、熔断机制来保障洪峰下的可用性。具体的技术细节可以参看电子书章节[1]
另外,考虑到在金融高频交易典型场景,我们也为RocketMQ设计了CP机制,在满足分布式系统的分区容错性的前提下,牺牲系统可用性来保证数据的一致性。而技术实现上,则基于Zab一致性协议,利用分布式锁和通知机制,以此来保障多副本数据的一致性。
开源捐赠和社区运营 目前国内外有很多公司会把一些通用问题的解决方案,尤其是那些久经考验、愈久弥坚的产品开源出来,以期望在品牌宣传、人才引进方面有所建树。把RocketMQ开源出来,甚至捐赠给Apache,内部也是经过了深思熟虑,层层审批与讨论,期望能够在生态化、规范化、国际化、商业化方面深耕细作。
开源捐赠的想法实际上始于2014年。当时,我们甄选了几位Apache社区权威人士,遗憾的是反复沟通不断修改草案之后突然间失去了联系。2015年,我们有幸结识了Kylin Principal Architect蒋旭和VP Luke以及Readhat Principal Software Engineer姜宁,请教了一些Apache禁忌事项,重新活跃起来了捐赠进程。接下来,最重要的是征集champion候选人,很开心的是ActiveMQ VP Bruce爽快地接收了我们的邀请,经过前前后后接近100封邮件来往,我们终于正式开启了Apache之旅。
捐赠投票是在双十一当天,我们准备充分很好地回答了评委会的犀利问题。不过,面对“中国开发者不喜欢邮件沟通”的突然刁难,还要感谢社区华人的防御性声明回应。经过很多磨难,投票结果总算出来了:还不算坏,10票赞同,带binding(IPMC成员的有效投票)的+1,无反对票,正式进入孵化期。孵化成功后有望成为国内首个互联网中间件在Apache上的顶级项目,成为全球继ActiveMQ,Kafka之后,分布式消息引擎家族中的重要成员。
接下来,我们想强调下知识产权这个对大多数工程师来说陌生的领域,尤其是专利权、著作权、商标权。在国外,每年因为这些问题导致的侵权官司不在少数。而我们在开源之初,对这块的选择、保护也是极其谨慎,包括开源许可协议的选择、授权方面,代码署名权等,这些都是很好的智力保护,也是我们产品的核心竞争力之一。尊重知识,尊重产权,才能构建一个和谐积极向上的开源氛围,打造真正的自主知识产权品牌产品。
在Alibaba,我们基于开源引擎的RocketMQ,为云上用户提供了商业化版本的Aliware MQ。两个产品都是由阿里中间件消息团队出品。商业版Aliware MQ 在支持 TCP 、HTTP 和MQTT 协议接入,功能方面增强了运维管控方面,生态集成的能力(包括可视化的消息轨迹、资源报表统计以及监控报警、Kafka集成等)。它在公有云上本身具备多机房部署同城高可用容灾特性,目的是满足企业级要求。
关于社区的运营,我们采取了和Apache顶级项目基本相似的策略。首先,必须立足于高质量产品本身,从版本规划开始,我们建立了里程碑讨论,Features设计,编码自测,结对Review,集成测试,Release讨论,Release公告等等一系列规范且高效的软件研发流程。其次,在社区运营层面,则有一系列与社区互动的活动,如线下meetup、workshop、ApacheCon、不定期的编程马拉松等,吸纳新的Contributor和Committer进来。
新一代RocketMQ,蓄势待发 最近,团队也在着手构建下一代RocketMQ,期望构建一套厂商无关的集线路层、API层于一体的规范,这也是第四代消息引擎最大的亮点。目前,我们联系了Twitter、Yahoo等公司相关技术负责人,共同起草完善这一规范,而RocketMQ将会是第一批率先成为参考实现的产品。我们非常期望国内的MQ厂商亦或是分布式爱好者能够参与进来,积极在国际开源社区代表国人发声呐喊。
另外,本周,团队刚刚发布了第四代引擎的第一个版本[5],该版本也是进入Apache社区后的首次发版。按照我们的规划,将在今年4月左右完成整个引擎的升级重组,非常欢迎大家的使用、反馈以及参与。
最后,关于资料的引用,具体可以从云栖社区【4】、中间件官方博客【3】、Apache RocketMQ主页【2】以及阿里巴巴电子书【1】甄选几篇。
官网地址:
https://rocketmq.incubator.apache.org/ 参考资料: [1] https://102.alibaba.com/newsInfo.htm?newsId=28&channel=126
[2] http://rocketmq.incubator.apache.org/docs/motivation/
[3] http://jm.taobao.org/2016/12/08/little-known-stories-about-apache-rocketmq/
[4] https://yq.aliyun.com/topic/76?spm=5176.8275330.622780.15.ZFUzya
[5] http://rocketmq.incubator.apache.org/release_notes/release-notes-4.0.0-incubating/
作者介绍
王小瑞,花名誓嘉,阿里巴巴中间件消息团队负责人,具有丰富的高可用,高可靠分布式系统构建经验,主导了阿里巴巴多次双十一消息引擎的改进优化项目,拥有多项分布式领域的专利。Apache RocketMQ联合创始人。联系方式:[email protected]
冯嘉,花名鼬神,阿里巴巴中间件架构师,具有丰富的分布式软件架构、高并发网站设计、性能调优经验,拥有多项分布式领域的专利。开源爱好者,专注分布式、大数据领域,关注Hbase/Hadoop/Spark/Flink等大数据技术栈。目前负责阿里消息中间件生态输出、云上商业化,Apache RocketMQ联合创始人。联系方式: [email protected]
今日荐文
点击下方图片即可阅读 腾讯HTTPS性能优化实践

本文来源:https://www.shanpow.com/jx/412208/

《mq消息中间件.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式

相关阅读
  • 六年级上册《桥》教学设计【汇编三篇】 六年级上册《桥》教学设计【汇编三篇】
  • 物体在斜面上运动教学设计精选九篇 物体在斜面上运动教学设计精选九篇
  • 守株待兔教学设计范文七篇 守株待兔教学设计范文七篇
  • 草船借箭教学设计范文三篇 草船借箭教学设计范文三篇
  • 人民解放战争的胜利教学设计【汇编七篇】 人民解放战争的胜利教学设计【汇编七篇】
  • 思政课教学设计集合5篇 思政课教学设计集合5篇
  • 二十四节气教案:谷雨节气活动方案- 幼儿园四季教学设计三篇 二十四节气教案:谷雨节气活动方案- 幼儿园四季教学设计三篇
  • 开天辟地的大事教学设计范文五篇 开天辟地的大事教学设计范文五篇
为您推荐
  • 教学设计评价(通用3篇)
    教学设计评价(通用3篇)
    《将相和》是人教版语文五年级上册第六课课文,这个故事出自司马迁的《史记·廉颇蔺相如列传》。下面是小编精心整理的教学设计评价(通用3篇),仅供参考,大家一起来看看吧。
  • 小学三年级数学下册《面积解决问题》教学设计及教学方案【八篇】
    小学三年级数学下册《面积解决问题》教学设计及教学方案【八篇】
    教学设计是根据课程标准的要求和教学对象的特点,将教学诸要素有序安排,确定合适的教学方案的设想和计划。一般包括教学目标、教学重难点、教学方法、教学步骤与时间分配等环节。以下是小编整理的小学三年级数学下册《面积解决问题》教学设计及教学方案【八篇】,欢迎阅读与收藏。
  • 初中历史教学设计精选三篇
    初中历史教学设计精选三篇
    教学设计是为了提高教学效率和教学质量,根据课程标准的要求和教学对象的特点,将教学诸要素有序安排,确定合适的教学方案的设想和计划,包括教学目标、教学方法、时间分配等环节。下面是小编精心整理的初中历史教学设计精选三篇,仅供参考,大家一起来看看吧。
  • 小学思政课教学设计【九篇】
    小学思政课教学设计【九篇】
    教学设计是根据课程标准的要求和教学对象的特点,将教学诸要素有序安排,确定合适的教学方案的设想和计划。一般包括教学目标、教学重难点、教学方法、教学步骤与时间分配等环节。以下是小编整理的小学思政课教学设计【九篇】,欢迎阅读与收藏。
  • 花钟教学设计一等奖_《花钟》教学设计范文(精选4篇)
    花钟教学设计一等奖_《花钟》教学设计范文(精选4篇)
    教学设计(Teachingdesign)是为了提高教学效率和教学质量,根据课程标准的要求和教学对象的特点,将教学诸要素有序安排,确定合适的教学方案的设想和计划,包括教学目标、教学方法、时间分配等环节。以下是小编为大家收集的花钟教学设计一等奖_《花钟》教学设计范文(精选4篇),仅供参考,欢迎大家阅读。
  • 高中化学思政课教学设计(合集七篇)
    高中化学思政课教学设计(合集七篇)
    思想政治课,是社会或社会群体用一定政治观点、道德规范,对其成员施加有目的、有计划、有组织的影响,使他们形成符合一定社会所要求的思想品德的社会实践活动。以下是小编整理的高中化学思政课教学设计(合集七篇),仅供参考,大家一起来看看吧。
  • 教学设计评价三篇
    教学设计评价三篇
    《将相和》是人教版语文五年级上册第六课课文,这个故事出自司马迁的《史记·廉颇蔺相如列传》。以下是为大家整理的教学设计评价三篇,欢迎品鉴!
  • 平移和旋转教学设计【汇编三篇】
    平移和旋转教学设计【汇编三篇】
    教学是教师的教和学生的学所组成的一种人类特有的人才培养活动。通过这种活动,教师有目的、有计划、有组织地引导学生学习和掌握文化科学知识和技能,促进学生素质提高,使他们成为社会所需要的人。下面是小编精心整理的平移和旋转教学设计【汇编三篇】,仅供参考,大家一起来看看吧。
  • 课堂教学提升思政素养的英语教学设计范文(精选四篇)
    课堂教学提升思政素养的英语教学设计范文(精选四篇)
    英语(English)属于印欧语系日耳曼语族西日耳曼语支,最早被中世纪的英国使用,并因其广阔的殖民地而成为世界使用面积最广的语言。英国人的祖先盎格鲁部落是后来迁移到大不列颠岛地区的日耳曼部落之一,称为英格兰。这两个名字都来自波罗地海半岛的An。以下是小编为大家收集的课堂教学提升思政素养的英语教学设计
  • 协商决定班级事务教学设计【六篇】
    协商决定班级事务教学设计【六篇】
    教学设计是根据课程标准的要求和教学对象的特点,将教学诸要素有序安排,确定合适的教学方案的设想和计划。一般包括教学目标、教学重难点、教学方法、教学步骤与时间分配等环节。以下是小编整理的协商决定班级事务教学设计【六篇】,欢迎阅读与收藏。