热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

RocketMQ开发指导之一——RocketMQ简介

本系列文章主要介绍RocketMQ的相关知识,并通过示例代码介绍RocketMQ的使用方法。本文为系列文章的第一篇,主要介绍RocketMQ的概要知识

本系列文章主要介绍 RocketMQ 的相关知识,并通过示例代码介绍 RocketMQ 的使用方法。

本文为系列文章的第一篇,主要介绍 RocketMQ 的概要知识。

说明:本文的部分内容参考了 https://www.jianshu.com/p/3afd610a8f7d 文章的相关内容。


1 概述

首先,给出 GitHub 上 RocketMQ 项目的描述,内容如下:


Apache RocketMQ is a distributed messaging and streaming platform with low latency, high performance and reliability, trillion-level capacity and flexible scalability.

It offers a variety of features:

  • Pub/Sub messaging model
  • Scheduled message delivery
  • Message retroactivity by time or offset
  • Log hub for streaming
  • Big data integration
  • Reliable FIFO and strict ordered messaging in the same queue
  • Efficient pull&push consumption model
  • Million-level message accumulation capacity in a single queue
  • Multiple messaging protocols like JMS and OpenMessaging
  • Flexible distributed scale-out deployment architecture
  • Lightning-fast batch message exchange system
  • Various message filter mechanics such as SQL and Tag
  • Docker images for isolated testing and cloud isolated clusters
  • Feature-rich administrative dashboard for configuration, metrics and monitoring

RocketMQ 作为一款分布式的消息中间件,经历了 Metaq1.x、Metaq2.x 的发展和淘宝双十一的洗礼,证明其在功能和性能上远超 ActiveMQ。GitHub 上关于 RocketMQ 诞生的原因中,也说明了随着交易量的大幅度增长,ActiveMQ 到达了性能瓶颈,而其他流行的消息解决方案(如 Kafka)都不能满足其需求的情况下,才诞生了 RocketMQ。

RocketMQ 的优点如下:


  • RocketMQ 原生就是支持分布式的,而 ActiveMQ 原生为单点性;
  • RocketMQ 可以保证严格的消息顺序,而 ActiveMQ 无法保证;
  • RocketMQ 提供亿级消息的堆积能力,这不是重点,重点是堆积了亿级的消息后,依然保持写入低延迟;
  • 丰富的消息拉取模式(Push or Pull)。Push 模式好理解,比如在消费者端设置 Listener 回调;而 Pull 模式,控制权在于消费者,即消费者需要主动地调用拉消息方法从 Broker 获取消息,这里面就存在一个消费位置记录的问题(如果不记录,会导致消息重复消费);
  • 在 Metaq1.x/2.x 的版本中,分布式协调采用的是 Zookeeper,而 RocketMQ 自己实现了一个 NameServer,这使得 RocketMQ 的分布式架构更加轻量级,性能更好;
  • 消息失败重试机制、高效的订阅者水平扩展能力、强大的API、事务机制。

2 Producer/Consumer Group

ActiveMQ 中并没有 Group 这个概念,而在 RocketMQ 中存在 Group 的机制,理解该机制对于深入理解 RocketMQ 非常重要。

RocketMQ 通过 Group 机制,天然地支持了消息负载均衡。例如,某个 Topic 有 9 条消息,其中一个 Consumer Group 有 3 个实例(3 个进程/3 台机器),那么每个实例将均摊 3 条消息,由此实现了负载均衡。(注意:RocketMQ 只有一种模式,即发布订阅模式)


3 集群模式

RocketMQ 有多种 Broker 集群部署模式,常见的包括:单 Master 模式、多 Master 模式、多 Master 多 Slave 模式(异步复制)、多 Master 多 Slave 模式(同步双写)等。这里需要强调一下:RocketMQ 的 Slave 只能被消费者读取,不可以被生产者写入,类似于 MySQL 的主从机制。下面分别介绍这几种 Broker 集群部署模式。


3.1 单Master模式

很显然,单 Master 模式部署风险较大,一旦这个 Broker 重启或宕机,会导致整个服务不可用,通常线上环境都不会使用此模式。


3.2 多Master模式

集群中全是 Master,没有 Slave,例如 2 个 Master 或 3 个 Master。此时,如果某一个 Broker 重启或宕机,对应用是无影响的。此模式的缺点在于,当某个 Master 宕机时,该 Master 上未被消费的消息在 Master 恢复之前是不可以订阅的,消息的实时性会受到影响。


3.3 多Master多Slave模式(异步复制)

此模式下,有多个 Master,每个 Master 会配置一个或多个 Slave,由此实现了系统的高可用性。同时,Master 与 Slave 之间的消息同步,采用异步复制的方式,主备之间会短暂的消息延迟,这种延迟是 MS 级别的。如果 Master 宕机,消费者可以从 Slave 上进行消息消费,不影响消息实时性,但是由于 Master 的宕机,会导致丢失掉极少量(尚未同步到 Slave 上)的消息。


3.4 多Master多Slave模式(同步双写)

此模式下,有多个 Master,每个 Master 会配置一个或多个 Slave,由此实现了系统的高可用性。同时,Master 与 Slave 之间的消息同步,采用同步双写的方式,也就是在 Master 和 Slave 都写成功的前提下,才会向应用(生产者)返回成功。显然,此种模式下,无论是数据还是服务都不是单点的,所以服务与数据的可用性都非常高。此模式的缺点在于,性能会比异步复制稍低。

多 Master 多 Slave 模式的部署架构图,如下所示:


4 RocketMQ vs ActiveMQ vs Kafka

下面给出一张 RocketMQ、ActiveMQ 和 Kafka 的技术和特性的对比表,表内容如下:


Messaging ProductClient SDKProtocol and SpecificationOrdered MessageScheduled MessageBatched MessageBroadCast MessageMessage FilterServer Triggered RedeliveryMessage StorageMessage RetroactiveMessage PriorityHigh Availability and FailoverMessage TrackConfigurationManagement and Operation Tools
ActiveMQJava, .NET, C++ etc.Push model, support OpenWire, STOMP, AMQP, MQTT, JMSExclusive Consumer or Exclusive Queues can ensure orderingSupportedNot SupportedSupportedSupportedNot SupportedSupports very fast persistence using JDBC along with a high performance journal,such as levelDB, kahaDBSupportedSupportedSupported, depending on storage,if using kahadb it requires a ZooKeeper serverNot SupportedThe default configuration is low level, user need to optimize the configuration parametersSupported
KafkaJava, Scala etc.Pull model, support TCPEnsure ordering of messages within a partitionNot SupportedSupported, with async producerNot SupportedSupported, you can use Kafka Streams to filter messagesNot SupportedHigh performance file storageSupported offset indicateNot SupportedSupported, requires a ZooKeeper serverNot SupportedKafka uses key-value pairs format for configuration. These values can be supplied either from a file or programmatically.Supported, use terminal command to expose core metrics
RocketMQJava, C++, GoPull model, support TCP, JMS, OpenMessagingEnsure strict ordering of messages,and can scale out gracefullySupportedSupported, with sync mode to avoid message lossSupportedSupported, property filter expressions based on SQL92SupportedHigh performance and low latency file storageSupported timestamp and offset two indicatesNot SupportedSupported, Master-Slave model, without another kitSupportedWork out of box,user only need to pay attention to a few configurationsSupported, rich web and terminal command to expose core metrics

5 Pull&Push模式

首先介绍一下 Push 和 Pull 两种消费模式,内容如下:


  • Push 模式:由消息中间件(MQ 消息服务器代理)主动地将消息推送给消费者。采用 Push 方式的情况下,broker 可以尽可能实时地将消息发送给消费者进行消费,但是,在消费者的处理消息的能力较弱时(比如消费者端的业务系统处理一条消息的流程比较复杂、其中的调用链路比较多导致消费时间比较久,概括起来就是“慢消费问题”),broker 不断地向消费者 Push 消息,会导致消费者端的缓冲区溢出,从而产生异常;
  • Pull 模式:由消费者主动向消息中间件(MQ 消息服务器代理)拉取消息。采用 Pull 方式时,重点是如何设置 Pull 消息的频率。例如,生产者可能在 1 分钟内连续生产了 1000 条消息,然后 2 小时内没有新消息产生,在这种情况下,如果每次 Pull 的时间间隔比较久,就会增加消息的延迟,即消息到达消费者的时间会加长,MQ 中消息的堆积量变大;反之,如果每次 Pull 的时间间隔较短,但是在一段时间内 MQ 中并没有任何消息可以消费,那么又会产生很多无效的 Pull 请求的 RPC 开销,影响 MQ 整体的网络性能(即“消息延迟与忙等待”)。

介绍完一般的 Push 与 Pull 消费方式后,再来看一下 RocketMQ 的这两种消费方式,内容如下:


  • RocketMQ 的 Pull 方式下,Consumer 主动获取 MessageQueue 的 Set(集合),遍历该集合中的每一个队列,发送 Pull 的请求(参数中带有队列中的消息偏移量),同时需要 Consumer 端自己保存消息消费的 offset(偏移量)至本地变量中。由此可见,在 Pull 模式下,需要业务应用自身去完成比较多的事情,所以在实际应用中,Pull 方式用的较少;
  • RocketMQ 的 Push 方式下,Consumer 注册了一个监听器,当 Consumer 收到消息时,会主动调用这个监听器完成消费,并进行相关的业务逻辑处理。由此可见,在 Push 方式下,业务应用代码只需要完成消息消费的代码逻辑即可,无需参与 MQ 本身的一些任务处理。

说明:RocketMQ 的 Push 方式本质上也属于 Pull 方式,因为当 Consumer 从 broker 成功获取到消息后,Consumer 需要调用监听器,主动去 broker 轮询拉取消息完成消费。这种 Push 方式既解决了普通的 Push 方式的“慢消费问题”,同时相对于纯 Pull 模式来说,在代码实现上又简单了许多。

正如上面的说明所述,RocketMQ 的消费方式(Pull 方式 和 Push 方式)本质上都是基于 Pull 方式的,即都是采用 consumer 轮询从 broker 拉取消息。而在轮询过程中,加入了一种长轮询机制(对普通轮询的一种优化),来平衡 Push/Pull 模型的各自缺点。长轮询机制的基本设计思路是:消费者如果第一次尝试 pull 消息失败(如 Broker 端没有可以消费的消息),Broker 并不立即给消费者客户端返回 Response 响应消息,而是先 hold 并挂起该请求(将请求保存至 pullRequestTable 本地缓存变量中),然后 Broker 端的后台独立线程 PullRequestHoldService 会从 pullRequestTable 本地缓存变量中不断地去取,具体的做法是查询待拉取消息的偏移量是否小于消费队列最大偏移量,如果条件成立则说明有新消息达到 Broker 端(这里,在 RocketMQ 的 Broker 端会有一个后台独立线程 ReputMessageService 不停地构建 ConsumeQueue/IndexFile 数据,同时取出 hold 住的请求并进行二次处理),则通过重新调用一次业务处理器 PullMessageProcessor 的处理请求方法 processRequest(),来重新尝试拉取消息(此处,每隔 5s 重试一次,默认长轮询整体的时间设置为 30s)。

RocketMQ 使用的这种长轮询机制(Pull 方式和 Push 方式都具有),解决了一般的 Push 方式的“慢消费问题”,同时,解决了一般的 Pull 方式的“消息延迟与忙等待问题”,并且,使用 RocketMQ 的 Push 机制,还可以减小消费者端的代码逻辑复杂度,所以 RocketMQ 的 Push 方式同时具有三个优点。

综上所述,在实际应用中,我们一般会采用 RocketMQ 的 Push 方式进行消息消费。

关于 RocketMQ 具体的部署方法,请参考本系列文章的第二篇。


推荐阅读
  • 从理想主义者的内心深处萌发的技术信仰,推动了云原生技术在全球范围内的快速发展。本文将带你深入了解阿里巴巴在开源领域的贡献与成就。 ... [详细]
  • ArcBlock 发布 ABT 节点 1.0.31 版本更新
    2020年11月9日,ArcBlock 区块链基础平台发布了 ABT 节点开发平台的1.0.31版本更新,此次更新带来了多项功能增强与性能优化。 ... [详细]
  • 本文详细介绍了如何在 Ubuntu 14.04 系统上搭建仅使用 CPU 的 Caffe 深度学习框架,包括环境准备、依赖安装及编译过程。 ... [详细]
  • Spring Security基础配置详解
    本文详细介绍了Spring Security的基础配置方法,包括如何搭建Maven多模块工程以及具体的安全配置步骤,帮助开发者更好地理解和应用这一强大的安全框架。 ... [详细]
  • 本文探讨了Python类型注解使用率低下的原因,主要归结于历史背景和投资回报率(ROI)的考量。文章不仅分析了类型注解的实际效用,还回顾了Python类型注解的发展历程。 ... [详细]
  • 利用Node.js实现PSD文件的高效切图
    本文介绍了如何通过Node.js及其psd2json模块,快速实现PSD文件的自动化切图过程,以适应项目中频繁的界面更新需求。此方法不仅提高了工作效率,还简化了从设计稿到实际应用的转换流程。 ... [详细]
  • 七大策略降低云上MySQL成本
    在全球经济放缓和通胀压力下,降低云环境中MySQL数据库的运行成本成为企业关注的重点。本文提供了一系列实用技巧,旨在帮助企业有效控制成本,同时保持高效运作。 ... [详细]
  • H5技术实现经典游戏《贪吃蛇》
    本文将分享一个使用HTML5技术实现的经典小游戏——《贪吃蛇》。通过H5技术,我们将探讨如何构建这款游戏的两种主要玩法:积分闯关和无尽模式。 ... [详细]
  • Docker安全策略与管理
    本文探讨了Docker的安全挑战、核心安全特性及其管理策略,旨在帮助读者深入理解Docker安全机制,并提供实用的安全管理建议。 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • 本文详细介绍了 `org.apache.tinkerpop.gremlin.structure.VertexProperty` 类中的 `key()` 方法,并提供了多个实际应用的代码示例。通过这些示例,读者可以更好地理解该方法在图数据库操作中的具体用途。 ... [详细]
  • CRZ.im:一款极简的网址缩短服务及其安装指南
    本文介绍了一款名为CRZ.im的极简网址缩短服务,该服务采用PHP和SQLite开发,体积小巧,约10KB。本文还提供了详细的安装步骤,包括环境配置、域名解析及Nginx伪静态设置。 ... [详细]
  • 回顾两年前春节期间的一个个人项目,该项目原本计划参加竞赛,但最终作为练习项目完成。独自完成了从编码到UI设计的全部工作,尽管代码量不大,但仍有一定的参考价值。本文将详细介绍该项目的背景、功能及技术实现。 ... [详细]
  • Jupyter Notebook多语言环境搭建指南
    本文详细介绍了如何在Linux环境下为Jupyter Notebook配置Python、Python3、R及Go四种编程语言的环境,包括必要的软件安装和配置步骤。 ... [详细]
  • Android与JUnit集成测试实践
    本文探讨了如何在Android项目中集成JUnit进行单元测试,并详细介绍了修改AndroidManifest.xml文件以支持测试的方法。 ... [详细]
author-avatar
大眼妹886
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有