【微服务专题】深入理解与实践微服务架构(二十四)之整合RocketMQ消息队列

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情

消息队列概述

消息队列是在消息的传输过程中保存消息的容器,用于接收消息并以文件的方式存储。消息队列作为高并发系统的核心组件之一,能够帮助业务系统解构提升开发效率和系统稳定性。

一个消息队列可以被一个也可以被多个消费者消费,包含以下 3 元素:

  • Producer: 消息生产者,负责产生和发送消息到 Broker。
  • Broker: 消息处理中心,负责消息存储、确认、重试等,一般其中会包含多个 Queue。
  • Consumer: 消息消费者,负责从 Broker 中获取消息,并进行相应处理。

主要具有以下优势:

  • 削峰填谷: 主要解决瞬时写压力大于应用服务能力导致消息丢失、系统奔溃等问题;
  • 系统解耦: 解决不同重要程度、不同能力级别系统之间依赖导致全局处理阻塞;
  • 提升性能: 当存在一对多调用时,可以发一条消息给消息系统,让消息系统通知相关系统;
  • 蓄流压测: 线上有些链路不好压测,可以通过堆积一定量消息再放开来压测。

用自己的话,简单总结一下就是:

  • 异步处理,提升性能
  • 更好的伸缩性
  • 削峰填谷
  • 失败隔离和自我修复
  • 系统解耦

消息队列应用场景

应用场景抽象

  • 异步通信:有些业务不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。
  • 解耦:降低工程间的强依赖程度,针对异构系统进行适配。在项目启动之初来预测将来项目会碰到什么需求,是极其困难的。通过消息系统在处理过程中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口,当应用发生变化时,可以独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
  • 冗余:有些情况下,处理数据的过程会失败。除非数据被持久化,否则将造成丢失。消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。许多消息队列所采用的”插入-获取-删除”范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。
  • 扩展性:因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外增加处理过程即可。不需要改变代码、不需要调节参数。便于分布式扩容。
  • 过载保护:在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量无法提取预知;如果以为了能处理这类瞬间峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
  • 可恢复性:系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
  • 顺序保证:在大多使用场景下,数据处理的顺序都很重要。大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。
  • 缓冲:在任何重要的系统中,都会有需要不同的处理时间的元素。消息队列通过一个缓冲层来帮助任务最高效率的执行,该缓冲有助于控制和优化数据流经过系统的速度。以调节系统响应时间。
  • 数据流处理:分布式系统产生的海量数据流,如:业务日志、监控数据、用户行为等,针对这些数据流进行实时或批量采集汇总,然后进行大数据分析是当前互联网的必备技术,通过消息队列完成此类数据收集是最好的选择。

实际常用的应用场景

上面主要介绍了消息队列的4大主要优势,下面介绍消息队列的实际应用场景:

  • 削峰填谷:当上下游系统处理能力存在差距的时候,利用消息队列做一个通用的”载体”,在下游有能力处理的时候,再进行分发与处理。诸如秒杀、抢红包、企业开门红等大型活动皆会带来较高的流量脉冲,很可能因没做相应的保护而导致系统超负荷甚至崩溃;或因限制太过导致请求大量失败而影响用户体验,RocketMQ可提供削峰填谷的服务来解决这些问题。
  • 异步解耦:消息队列减少了服务之间的耦合性,不同的服务可以通过消息队列进行通信,而不用关心彼此的实现细节。像交易系统作为淘宝/天猫主站最核心的系统,每笔交易订单数据的产生会引起几百个下游业务系统的关注。包括物流、购物车、积分、流计算分析等,整体业务系统庞大而且复杂;RocketMQ可实现异步通信和应用解耦,确保主站业务的连续性。
  • 顺序收发:证券交易过程中的时间优先原则,交易系统中的订单创建、支付、退款等流程,航班中的旅客登机消息处理等与先进先出(First In First Out,缩写FIFO)原理类似,RocketMQ提供的顺序消息即保证消息的FIFO。
  • 日志处理: 日志处理是指将消息队列用在日志处理中,比如 Kafka 的应用,解决大量日志传输的问题。
  • 消息通讯: 消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯,比如实现点对点消息队列,或者聊天室等。
  • 消息广播: 如果没有消息队列,每当一个新的业务方接入,我们都要接入一次新接口。有了消息队列,我们只需要关心消息是否送达了队列,至于谁希望订阅,是下游的事情,无疑极大地减少了开发和联调的工作量。
  • 分布式缓存同步:对于数据库与缓存数据之间的超时时间不好控制,可以通过消息队列异步通知缓存进行数据变更。双11大促商品需要实时感知价格的变化,大量并发访问会导致会场页面响应时间长;集中式缓存因为带宽瓶颈限制商品变更的访问流量,通过RocketMQ构建分布式缓存,可实时通知商品数据的变化。
  • 分布式事务一致性:交易系统、红包等场景需要确保数据的最终一致性,大量引入RocketMQ的分布式事务既可以实现系统之间的解耦,又可以保证最终的数据一致性。
  • 大数据分析:数据在“流动”中产生价值,传统数据分析大都基于批量计算模型,无法做到实时的数据分析。利用RocketMQ与流式计算引擎相结合,可以很方便地实现对业务数据进行实时分析。

消息队列技术选型

1. ActiveMQ

  • 优点:单机吞吐量万级,时效性ms(毫秒)级别,可用性高,基于主从架构实现高可用性,很难丢失数据消息。
  • 缺点:官方社区对ActiveMQ5.x 的维护越来越少,高吞吐量场景较少使用。

2. RabbitMQ

2007年发布的,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息系统,是当前最主流的消息中间件之一。

  • 优点:由于erlang语言的高并发特征,性能较好;吞吐量到万级,MQ的功能比较健壮、完善、易用、跨平台。 支持多语言:Java、PHP、C++、Python等等;开源提供的界面非常棒,社区活跃度较高,更新频率相当的高。
  • 缺点:商业版的学习成本较高。

3. Kafka

大数据的杀手锏,谈到大数据领域内的消息传输,则绕不开Kafka,这款为大数据而生的消息中间件,以百万级TPS的吞吐量名声大噪,迅速成为大数据领域的宠儿,在数据采集、传输、存储的过程中发挥着举足轻重给的作用。

TPS就是系统的吞吐量

功能支持:功能比较简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用。

  • 优点:性能卓越,单机写入TPS约在百万条/秒。最大的优点就是吞吐量高。时效性ms级可用性非常高,Kafka是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用,消费者采用pull方式获取消息,消息是有序的。通过控制能够保证所有的消息都被消费且仅被消费一次。有优秀的第三方管理界面;在日志方面也较为成熟。
  • 缺点:Kafka单机超过64个队列/分区,Load会发生明显的飙高现象,队列越多,load越高,发送消息响应时间变长,使用的是 短轮询的方式,时效性取决于轮询间隔时间。 小时失败不支持重试;支持消息顺序,但是如果一台代理宕机,就会产生消息乱序,社区更新较慢。

4. RocketMQ

RocketMQ是出自阿里巴巴的开源产品,用Java语言编写的,在设计时参考了Kafka,并做出了一些自己的改进。被阿里巴巴广泛应用在订单,交易,充值,流计算,消息推送,日志处理等方面。

  • 优点单机吞吐量十万级,可用性非常高,是分布式架构,消息可以做到0丢失,MQ功能较为完善,还是发呢分布式的,扩展性好, 支持10亿级别的消息堆积。不会因为消息堆积而导致性能下降,源码是Java,我们可以自己订阅源码,定制自己公司的MQ。
  • 缺点支持的客户端语言不多,目前仅支持Java以及C++,其中C++不成熟。 社区活跃度不高,没有在MQ核心中去实现JMS等接口,有些系统要迁移需要修改大量的代码。

5. ZeroMQ

号称最快的消息队列系统,专门为高吞吐量/低延迟的场景开发,在金融界的应用中经常使用,偏重于实时数据通信场景。ZMQ能够实现RabbitMQ不擅长的高级/复杂的队列,但是开发人员需要自己组合多种技术框架,开发成本高。因此ZeroMQ具有一个独特的非中间件的模式,更像一个socket library,你不需要安装和运行一个消息服务器或中间件,因为你的应用程序本身就是使用ZeroMQ API完成逻辑服务的角色。但是ZeroMQ仅提供非持久性的队列,如果down机,数据将会丢失。如:Twitter的Storm中使用ZeroMQ作为数据流的传输。

ZeroMQ套接字是与传输层无关的:ZeroMQ套接字对所有传输层协议定义了统一的API接口。默认支持 进程内(inproc) ,进程间(IPC) ,多播,TCP协议,在不同的协议之间切换只要简单的改变连接字符串的前缀。可以在任何时候以最小的代价从进程间的本地通信切换到分布式下的TCP通信。ZeroMQ在背后处理连接建立,断开和重连逻辑。

优点

  • 无锁的队列模型:对于跨线程间的交互(用户端和session)之间的数据交换通道pipe,采用无锁的队列算法CAS;在pipe的两端注册有异步事件,在读或者写消息到pipe的时,会自动触发读写事件。
  • 批量处理的算法:对于批量的消息,进行了适应性的优化,可以批量的接收和发送消息。
  • 多核下的线程绑定,无须CPU切换:区别于传统的多线程并发模式,信号量或者临界区,zeroMQ充分利用多核的优势,每个核绑定运行一个工作者线程,避免多线程之间的CPU切换开销。

缺点:更类似于一个网络库,与libev和libuv高性能网络库比较类似,因为不支持持久化因此高可用方面不足。

参考比较:

  • RabbitMQ是一个AMQP实现,传统的messaging queue系统实现,基于Erlang的消息队列。老牌MQ产品了,AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量还在其次。
  • Kafka是linkedin开源的MQ系统,主要特点是基于Pull的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输,0.8开始支持复制,不支持事务,适合产生大量数据的互联网服务的数据收集业务。Kafka主要做日志订阅,着重数据流处理。
  • ZeroMQ只是一个网络编程的Pattern库,将常见的网络请求形式(分组管理,链接管理,发布订阅等)模式化、组件化,简而言之socket之上、MQ之下。对于MQ来说,网络传输只是它的一部分,更多需要处理的是消息存储、路由、Broker服务发现和查找、事务、消费模式(ack、重投等)、集群服务等。ZeroMQ主要是做本地进程之间的协调(coordination),方便socket之间网络通信。

简单总结:

  • ActiveMQ

    • Java开发,简单、稳定,效率不高
  • RabbitMQ

    • erlang开发
    • 对消息堆积支持不友好
  • Kafka

    • Scala开发
    • 效率高
    • 消息丢失概率大,适合做日志收集、埋点上报等业务
  • RocketMQ

    • Java开发
    • 集群化,效率高,每秒可处理几十万条消息
    • 有消息查询界面
    • 消息可靠性高

下面是以表格形式进行的详细对比:

消息队列的对比

下面对比了几大主流消息队列,功能特点之间的联系和区别:

特性 ActiveMQ RabbitMQ Kafka RocketMQ
PRODUCER-COMSUMER 支持 支持 支持 支持
PUBLISH-SUBSCRIBE 支持 支持 支持 支持
REQUEST-REPLY 支持 支持 - 支持
API完备性 低(静态配置)
多语言支持 支持,JAVA优先 语言无关 支持,JAVA优先 支持
单机呑吐量 万级 万级 十万级 单机万级
消息延迟 - 微秒级 毫秒级 -
可用性 高(主从) 高(主从) 非常高(分布式)
消息丢失 - 理论上不会丢失 -
消息重复 - 可控制 理论上会有重复 -
文档的完备性
提供快速入门
首次部署难度 -

MQ的选择

  1. Kafka:Kafka主要的特是基于Pull的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输,适合产生大量数据的互联网服务的数据收集业务,大型公司建议使用。
  2. RocketMQ : 天生为金融互联网而生,对于可靠性要求很高的场景,尤其是电商里面的订单扣款,以及业务消峰,在大量交易涌入的时候,后端可能无法及时处理。RocketMQ在稳定性上可能更值得信赖,这些业务场景在阿里双11已经经历了多次的考验,如果你的业务有上述的场景发生,建议可以使用RocketMQ。
  3. RabbitMQ :结合erlang语言本身并发优势,性能好时效性微秒级,社区活跃度比较高,管理界面十分方面,如果你的数据量没有那么大,中小型公司优先选择功能完善的RabbitMQ。

还有其他像Pulsar、EMQX等消息队列这里暂不一一分析了,就分析了上面微服务架构中几大主流消息队列。

参考:

消息中间件相关知识

  • Producer:消息生产者,业务的发起方,负责生产消息传输给broker。
  • Consumer:消息消费者,业务的处理方,负责从broker获取消息并进行业务逻辑处理。
  • Broker:消息代理服务器,作为server提供消息核心服务。
  • Topic:主题,Pub/Sub(发布/订阅)模式下的消息统一汇集地,不同生产者向topic发送消息,由MQ服务器分发到不同的订阅者,实现消息的广播。
  • Queue:队列,PTP模式下,特定生产者向特定queue发送消息,消费者订阅特定的queue完成指定消息的接收。
  • Message:消息体,根据不同通信协议定义的固定格式进行编码的数据包,来封装业务数据,实现消息的传输。

RocketMQ 介绍

阿里旗下一款开源的分布式、队列模型的消息中间件,原名MetaQ,3.0版本名称改为RocketMQ。

是阿里参照kafka设计思想使用java实现的一套mq。同时将阿里系内部多款mq产品(Notify、metaq)进行整合,只维护核心功能,去除了所有其他运行时依赖,保证核心功能最简化,在此基础上配合阿里上述其他开源产品实现不同场景下mq的架构,目前主要多用于订单交易系统。

下面是官方文档介绍:

Apache RocketMQ是一个分布式消息和流媒体平台,具有低延迟、高性能和可靠性、万亿级容量和灵活的可扩展性。

它提供了多种功能:

  • 消息传递模式,包括发布/订阅、请求/回复和流式传输
  • 金融级交易信息
  • 基于DLedger Controller的内置容错和高可用性配置选项
  • 内置消息追踪能力,也支持opentracing
  • 多功能大数据和流媒体生态系统集成
  • 按时间或偏移量追溯消息
  • 可靠的 FIFO 和严格有序的消息在同一个队列中
  • 高效拉推消费模式
  • 单队列百万级消息积累能力
  • 多种消息传递协议,如 gRPC、MQTT、JMS 和 OpenMessaging
  • 灵活的分布式横向扩展部署架构
  • 闪电般的批量消息交换系统
  • 各种消息过滤机制,例如 SQL 和 Tag
  • 用于隔离测试和云隔离集群的 Docker 映像
  • 用于配置、指标和监控的功能丰富的管理仪表板
  • 身份验证和授权
  • 免费的开源连接器,用于源和接收器
  • 轻量级实时计算

RocketMQ 优势

RocketMQ对比ActiveMQ、kafka、RabbitMQ,其主要优势有:

  • 支持事务型消息(消息发送和 DB 操作保持两方的最终一致性,RabbitMQ 和 Kafka 不支持)
  • 支持结合 RocketMQ 的多个系统之间数据最终一致性(多方事务,二方事务是前提)
  • 支持 18 个级别的延迟消息(RabbitMQ 和 Kafka 不支持)
  • 支持指定次数和时间间隔的失败消息重发(Kafka 不支持,RabbitMQ 需要手动确认)
  • 支持 Consumer 端 Tag 过滤,减少不必要的网络传输(RabbitMQ 和 Kafka 不支持)
  • 支持重复消费(RabbitMQ 不支持,Kafka 支持)

因此,针对这些优点,RocketMQ可以有下面几大常见的使用场景:

  1. 普通消息(订阅)

    -- RocketMQ之二:分布式开放消息系统RocketMQ的原理与实践(消息的顺序问题、重复问题、可靠消息/事务消息)

  2. 顺序消息

    -- RocketMQ之二:分布式开放消息系统RocketMQ的原理与实践(消息的顺序问题、重复问题、可靠消息/事务消息)

  3. 广播消息

  4. 延时消息

  5. 批量消息

  6. 事务消息

参考:RocketMQ之一:RocketMQ整体介绍

下面是其他的参考介绍:

缘起

RocketMQ诞生的历史:

  1. 阿里内部为了适应淘宝更快、更复杂的业务,在2001年启动了「五彩石项目」,第一代消息队列服务Notify在这个背景下应运而生。
  2. 2010年ActiveMQ仍然作为核心技术广泛应用于阿里内部各个业务线,与此同时,支持顺序消息、事务消息、海量消息堆积的消息服务也是阿里急需的,在这种背景下,2011年MetaQ诞生。
  3. 2011年Kafka开源,2012年阿里参考Kafka的设计,研发了一套通用的消息队列引擎,第一代RocketMQ诞生。
  4. 2016年,阿里云上线RocketMQ消息队列云服务。同年11月,阿里将RocketMQ捐献给Apache基金会,开始孵化。
  5. 2017年9月25日,RocketMQ顺利“毕业”,成为Apache顶级项目。

特性

  1. 削峰填谷
  2. 服务解耦
  3. 异步处理
  4. 分布式事务最终一致性

功能

  • Topic发布订阅模型
  • 消息过滤
  • 至少一次投递(允许多次)
  • 回溯消费
  • 顺序消息
  • 事务消息
  • 延迟消息
  • 消息重试
  • 消息重投
  • 流量控制
  • 死信队列

参考:RocketMQ技术分享

下载RocketMQ

RocketMQ 运行在所有主流操作系统上,只需要安装 JDK 8 或更高版本。要检查,请运行java -version

$ java -version
java version "1.8.0_121"
复制代码

然后我们可以在Github的镜像仓库或者Apache社区下载二进制安装包:

目前RocketMQ最新版是4.9.4,但我们对应Spring Cloud Alibaba对应的稳定版本时4.9.2,因此我们还是下载推荐的稳定版本

# Github镜像源码下载(不推荐,需要手动编译)
https://codeload.github.com/apache/rocketmq/zip/refs/tags/rocketmq-all-4.9.2# Apache社区镜像下载(推荐,已编译好)
https://archive.apache.org/dist/rocketmq/4.9.2/rocketmq-all-4.9.2-bin-release.zip
复制代码

下面是Apache RocketMQ社区的RocketMQ,对应Release包的发行页面:

rocketmq.apache.org/release_not…

image-20220728023136126

下载完成后,我们就得到了可直接运行的二进制包。

解压,解压后的文件夹如下所示:

image-20220728040350892

注意:解压路径不要有空格,否则后面运行会报错失败(如果解压路径有空格了,重新解压到没有空格的路径)。

cd 切换到 bin 目录中,即可看到启动命令脚本,后面安装启动需要用到启动脚本。

cd rocketmq-4.9.2/bin
复制代码

到此,我们RocketMQ下载就完成了,下面进行安装:

安装RocketMQ

Windows客户端安装

对于 Windows 用户,您需要先设置环境变量:

  • 在桌面上,右键单击计算机图标。
  • 从上下文菜单中选择属性。
  • 单击高级系统设置链接。
  • 单击环境变量。
  • 添加环境ROCKETMQ_HOME="D:\DevCenter\Spring Cloud Alibaba\RocketMQ\rocketmq-4.9.2"

image-20220728040713523

注意

  • JDK路径和RocketMQ路径都不能有空格,否则会启动失败;
  • 另外,这里也无需配置环境变量到Path里。

然后将目录更改为rocketmq,键入并运行:

$ mqnamesrv.cmd
The Name Server boot success...
复制代码
  • 一定需要将解压后的rocketmq-4.9.2设置为系统环境变量。

如果不设置环境变量,直接在命令行启动 mqnamesrv.cmd 脚本,会报以下错误提示:

D:\DevCenter\Spring Cloud Alibaba\RocketMQ\rocketmq-4.9.2\bin>mqnamesrv.cmd
Please set the ROCKETMQ_HOME variable in your environment!
复制代码

注意事项总结

  • RocketMQ安装路径的文件名不能有空格,jdk安装路径的文件名也不能有空格。
  • runbroker.cmd文件,%CLASSPATH%需要添加双引号。
  • 修改RocketMQ最小和最大启动内存为512m。

第一种情况:如果JDK或RocketMQ这两者,其中一个安装路径有空格,会出现以下错误:

D:\DevCenter\Spring Cloud Alibaba\RocketMQ\rocketmq-4.9.2\bin>mqnamesrv.cmd
Java HotSpot(TM) 64-Bit Server VM warning: Using the DefNew young collector with the CMS collector is deprecated and will likely be removed in a future release
Java HotSpot(TM) 64-Bit Server VM warning: UseCMSCompactAtFullCollection is deprecated and will likely be removed in a future release.
错误: 找不到或无法加载主类 Cloud
复制代码

这里我们如果原来配置的就是有空格的安装路径,那么我们需要去除JDK或RocketMQ安装路径空格后,重新配置系统环境变量

正好我们一直没有使用Nacos 1.4.2而是使用的Nacos 1.4.1,正好趁此机会我们使用Nacos 1.4.2:

  1. 首先停止并卸载Nacos服务(控制台访问测试),然后修改带空格的上层路径Spring Cloud Alibaba为SpringCloudAlibaba;接着修改Nacos 1.4.1的nacos-service.xml服务配置文件(下次可以正常服务启动) ,这时旧Nacos服务自启动就解除了,下面配置新版本的Nacos服务。

  2. 解压Nacos 1.4.2到Nacos 1.4.1同级目录下,然后将Nacos 1.4.1根目录下的plugin插件文件夹复制到Nacos 1.4.2根目录下,接着复制Nacos 1.4.1的bin目录下的服务启动文件到Nacos 1.4.2的bin目录下;修改bin目录下的nacos-service.xml服务配置文件,修改Nacos的conf目录下application.properties配置文件的mysql相关配置(记得去除useSSL=false参数,并调大连接超时时间),在bin目录下重新注册服务然后启动即可。

  3. 重新访问 http://localhost:8848/nacos 即可看到控制台数据(注意不是 http://localhost:8848,不带nacos后缀会出现404错误页面),因为mysql数据是可以共享的,因此原来的配置不会丢失。

    image-20220728035609418

  4. sentinel的服务改造同理。

如果怀疑不是路径带空格导致启动错误的原因,那么可以复解压文件夹到无空格的路径下,配置环境变量测试;经过尝试后,可以证明的确是路径带空格的原因。因此,这里也给了我们安装软件的警示:安装路径最好为英文,并且不带空格

第二种情况:有可能在启动RocketMQ的NameServer之后,启动Broker会发生错误。

第三种情况:在正常启动RocketMQ时,会出现以下警告:

D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin>mqnamesrv.cmd
Java HotSpot(TM) 64-Bit Server VM warning: Using the DefNew young collector with the CMS collector is deprecated and will likely be removed in a future release
Java HotSpot(TM) 64-Bit Server VM warning: UseCMSCompactAtFullCollection is deprecated and will likely be removed in a future release.
The Name Server boot success. serializeType=JSON
复制代码

原因是RocketMQ默认启动内存是4G,我们电脑虚拟机一般内存有限,没有这么大内存。所以我们得修改这个值,把值修改为256m,得修改两个配置文件: runserver.sh 和runbroker.sh(windows平台就是对应名称的cmd文件)

runserver.cmd

set "JAVA_OPT=%JAVA_OPT% -server -Xms2g -Xmx2g -Xmn1g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
set "JAVA_OPT=%JAVA_OPT% -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:-UseParNewGC"
set "JAVA_OPT=%JAVA_OPT% -verbose:gc -Xloggc:"%USERPROFILE%\rmq_srv_gc.log" -XX:+PrintGCDetails -XX:+PrintGCDateStamps"
set "JAVA_OPT=%JAVA_OPT% -XX:-OmitStackTraceInFastThrow"
set "JAVA_OPT=%JAVA_OPT% -XX:-UseLargePages"
set "JAVA_OPT=%JAVA_OPT% -Djava.ext.dirs=%BASE_DIR%lib;%JAVA_HOME%\jre\lib\ext"
set "JAVA_OPT=%JAVA_OPT% -cp "%CLASSPATH%""
​
"%JAVA%" %JAVA_OPT% %*
复制代码

上面的 -Xms2g -Xmx2g -Xmn1g 修改为 -Xms512m -Xmx512m -Xmn128m

注意:这里 set "JAVA_OPT=%JAVA_OPT% -cp "%CLASSPATH%"" 中的 CLASSPATH 需要添加 "",否则会出现"无法加载主类"的错误。

Rem set "JAVA_OPT=%JAVA_OPT% -server -Xms2g -Xmx2g -Xmn1g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
set "JAVA_OPT=%JAVA_OPT% -server -Xms512m -Xmx512m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
复制代码

我这边是开发环境不需要设置太高的内存,生产环境的话2g是比较合适的,因此针对环境不同设置不同的JVM参数(最小堆内存、最大堆内存、青年代内存、最小元空间内存和最大元空间内存)

runbroker.cmd

rem ===========================================================================================
rem  JVM Configuration
rem ===========================================================================================
set "JAVA_OPT=%JAVA_OPT% -server -Xms2g -Xmx2g"
set "JAVA_OPT=%JAVA_OPT% -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:SurvivorRatio=8"
set "JAVA_OPT=%JAVA_OPT% -verbose:gc -Xloggc:%USERPROFILE%\mq_gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy"
set "JAVA_OPT=%JAVA_OPT% -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m"
set "JAVA_OPT=%JAVA_OPT% -XX:-OmitStackTraceInFastThrow"
set "JAVA_OPT=%JAVA_OPT% -XX:+AlwaysPreTouch"
set "JAVA_OPT=%JAVA_OPT% -XX:MaxDirectMemorySize=15g"
set "JAVA_OPT=%JAVA_OPT% -XX:-UseLargePages -XX:-UseBiasedLocking"
set "JAVA_OPT=%JAVA_OPT% -Djava.ext.dirs=%BASE_DIR%lib;%JAVA_HOME%\jre\lib\ext"
set "JAVA_OPT=%JAVA_OPT% -cp "%CLASSPATH%""
复制代码

上面的 -Xms2g -Xmx2g 修改为 -Xms512m -Xmx512m

rem set "JAVA_OPT=%JAVA_OPT% -server -Xms2g -Xmx2g"
set "JAVA_OPT=%JAVA_OPT% -server -Xms512m -Xmx512m"
复制代码

可以发现,NameServer和Broker这两个组件之间使用的垃圾回收器不是一样的,一个为CMS而另一是G1垃圾回收器。

其他知识

:: 这是注释内容
Rem 这也是注释内容
Del /q /s "%temp%*.*"&Rem 清空临时文件
复制代码

到此,RocketMQ的安装步骤就已经完成,下面进行正常的启动:

启动RocketMQ

Windows 启动

完成上面的安装排坑之旅后,我们下面可以启动RocketMQ了,需要分为NameServerBroker这两部分启动:

1、启动NameServer

进入bin目录,在路径中输入cmd,回车打开控制台窗口,然后输入以下命令启动NameServer:

D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin>mqnamesrv.cmd
Java HotSpot(TM) 64-Bit Server VM warning: Using the DefNew young collector with the CMS collector is deprecated and will likely be removed in a future release
Java HotSpot(TM) 64-Bit Server VM warning: UseCMSCompactAtFullCollection is deprecated and will likely be removed in a future release.
The Name Server boot success. serializeType=JSON
复制代码

注意:不要关闭当前窗口,因为Broker代理服务器依赖于NameServer的启动。

脚本快速启动D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin 目录下创建文件 mqnamesrv-start.cmd ,内容如下:

@echo off
D:
cd D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin
mqnamesrv.cmd
复制代码

静默启动脚本mqnamesrv-silence.bat:

@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("%~nx0 h",0)(window.close)&&exit
:begin
D:
cd "D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin"
mqnamesrv.cmd
复制代码

关闭脚本mqnamesrv-shutdown.cmd:

@echo off
D:
cd D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin
mqshutdown namesrv
复制代码

nameserver注册为windows服务

如果我们想要不用每次开机都手动点击脚本运行RocketMQ,并且希望后台运行,我们可以通过注册为服务来实现:

下载 Windows Service Wrapper工具

这是利用xml配置文件将cmd一键注册为windows系统服务的,像这种工具还有 nssm

下载地址:github.com/winsw/winsw…

编写rocketmq-nameserver-service.xml配置文件

和上面的Nacos服务注册配置一样,同样需要配置rocketmq-nameserver服务的配置文件,然后注册这个服务。

  • 将下面的服务启动服务配置服务注册服务卸载文件都统一放置在\bin\scripts\nameserver目录下。

  • 将WinSW-X64.exe(或WinSW.NET4.exe)重命名为rocketmq-nameserver-service.exe,复制后放在RocketMQ的NameServer目录下;

    注意:rocketmq-nameserver-service.exe文件需要放置在与启动文件的同级目录,否则服务注册了不能启动成功!

  • 创建配置文件rocketmq-nameserver-service.xml,并添加服务配置(注意: 服务名称不要为中文):

    <?xml version="1.0" encoding="UTF-8" ?>
    <service>
      <!-- 唯一服务ID,这必须是唯一的,它应该完全由字母数字字符组成-->
      <id>RocketMQ-NameServer</id>
      <!-- 显示服务的名称 -->
      <name>RocketMQ NameServer Service</name>
      <!-- 服务描述 -->
      <description>RocketMQ命名服务器服务</description>
      <!-- 日志路径 -->
      <logpath>D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\logs\nameserver-logs</logpath>
      <!-- 日志模式 -->
      <logmode>roll</logmode>
      <!-- 可执行文件的命令 -->
      <executable>D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin\scripts\nameserver\mqnamesrv-start.cmd</executable>
      <!-- 停止可执行文件的命令 -->
      <stopexecutable>D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\scripts\nameserver\mqnamesrv-shutdown.cmd</stopexecutable>
    </service>
    复制代码

下面的部分可以手动点击完成,命令行只是从原理介绍

注册和卸载rocketmq-nameserver服务

# rocketmq-nameserver-service-install.cmd服务注册脚本
@echo off
rocketmq-nameserver-service.exe install
​
# rocketmq-nameserver-service-install.cmd服务卸载脚本
@echo off
rocketmq-nameserver-service.exe uninstall
复制代码

启动和关闭服务(需要管理员模式运行cmd)

# 启动RocketMQ-NameServer服务
D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin\scripts\nameserver>net start RocketMQ-NameServer
RocketMQ NameServer Service 服务正在启动 .
RocketMQ NameServer Service 服务已经启动成功。
​
# 停止RocketMQ-NameServer服务
D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin\scripts\nameserver>net stop RocketMQ-NameServer
RocketMQ NameServer Service 服务正在停止......
RocketMQ NameServer Service 服务已成功停止。
复制代码

注意:上面rocketmq-nameserver-service.xml中配置的id标签中的才是服务名,而name标签只是显示服务名。

另外,如果使用net start开启服务命令发生如下错误:

D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin\scripts\nameserver>net start RocketMQ-NameServer
发生系统错误 5。
​
拒绝访问。
复制代码

请在管理员模式下开启cmd命令行窗口。如果觉得手动打开管理模式的cmd控制台,然后cd切换路径到其他盘符很麻烦,可以编写下面打开管理员模式下的本路径的cmd窗口脚本cmd-admin-test.cmd:

@echo off
D:
cd D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin\scripts\nameserver
start
复制代码

查看Windows服务

win + R打开运行,输入以下命令打开windows服务列表进行查看:

services.msc
复制代码

到此,服务注册完成,并且成功启动!

2、启动Broker

同样的,在bin目录下另开一个命令行窗口,然后启动Broker:

D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin>mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true
The broker[aries, 192.168.80.1:10911] boot success. serializeType=JSON and name server is 127.0.0.1:9876
复制代码

同样的,Broker的命令窗口也不要关闭。

脚本快速启动 D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin 目录下创建文件 mqbroker-start.cmd ,内容如下:

@echo off
D:
cd D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin
mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true
复制代码

后台静默启动脚本mqbroker-silence.bat:

@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("%~nx0 h",0)(window.close)&&exit
:begin
D:
cd "D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin"
mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true
复制代码

关闭脚本mqbroker-shutdown.cmd:

@echo off
cd ../
mqshutdown broker
复制代码

broker注册为windows服务

如果我们想要不用每次开机都手动点击脚本运行RocketMQ,并且希望后台运行,我们可以通过注册为服务来实现:

下载 Windows Service Wrapper工具

这是利用xml配置文件将cmd一键注册为windows系统服务的,像这种工具还有 nssm

下载地址:github.com/winsw/winsw…

编写rocketmq-broker-service.xml配置文件

和上面的Nacos服务注册配置一样,同样需要配置rocketmq-broker服务的配置文件,然后注册这个服务。

  • 将下面的服务启动服务配置服务注册服务卸载文件都统一放置在\bin\scripts\broker目录下。

  • 将WinSW-X64.exe(或WinSW.NET4.exe)重命名为rocketmq-broker-service.exe,复制后放在RocketMQ的Broker目录下;

    注意:rocketmq-broker-service.exe文件需要放置在与启动文件的同级目录,否则服务注册了不能启动成功!

  • 创建配置文件rocketmq-broker-service.xml,并添加服务配置(注意: 服务名称不要为中文):

    <?xml version="1.0" encoding="UTF-8" ?>
    <service>
      <!-- 唯一服务ID-->
      <id>RocketMQ-Broker</id>
      <!-- 显示服务的名称 -->
      <name>RocketMQ Broker Service</name>
      <!-- 服务描述 -->
      <description>RocketMQ代理服务器服务</description>
      <!-- 日志路径 -->
      <logpath>D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\logs\broker-logs</logpath>
      <!-- 日志模式 -->
      <logmode>roll</logmode>
      <!-- 可执行文件的命令 -->
      <executable>D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\bin\scripts\broker\mqbroker-start.cmd</executable>
      <!-- 停止可执行文件的命令 -->
      <stopexecutable>D:\DevCenter\SpringCloudAlibaba\RocketMQ\rocketmq-4.9.2\scripts\broker\mqbroker-shutdown.cmd</stopexecutable>
    </service>
    复制代码

下面的部分可以手动点击完成,命令行只是从原理介绍

注册和卸载rocketmq-broker服务

# rocketmq-broker-service-install.cmd服务注册脚本
@echo off
rocketmq-broker-service.exe install
​
# rocketmq-broker-service-install.cmd服务卸载脚本
@echo off
rocketmq-broker-service.exe uninstall
复制代码

启动和关闭服务(需要管理员模式运行cmd)

# 启动RocketMQ-Broker服务
net start RocketMQ-Broker
​
# 停止RocketMQ-Broker服务
net stop RocketMQ-Broker
复制代码

注意:上面rocketmq-broker-service.xml中配置的id标签中的才是服务名,而name标签只是显示服务名。

查看Windows服务

win + R打开运行,输入以下命令打开windows服务列表进行查看:

services.msc
复制代码

到此,服务注册完成,并且成功启动!

到此为止,RocketMQ的已经成功启动!

但是只有后端服务提供。我们如果想要在控制台界面看到RocketMQ消息队列的详情,还需要安装RocketMQ控制台(下面进行安装)。

Linux 启动

1.RocketMQ zip包传入linux服务器

[root@localhost ]# cd usr/local/
[root@localhost local]# rz
复制代码

2.解压缩

[root@localhost local]# unzip rocketmq-all-4.8.0-bin-release.zip
复制代码

3.调整启动参数(修改默认启动参数,默认启动的最大内存为4G,比较大,修改小一点,否则如果服务器内存不够会启动失败)

[root@localhost local]# cd rocketmq-all-4.8.0-bin-release/bin
[root@localhost bin]# vim runserver.sh
复制代码

img

  • -Xms4g -Xmx4g -Xmn2g 改为 -Xms256m -Xmx256m -Xmn128m

img

4.调整broker

[root@localhost bin]# vim runbroker.sh
复制代码

img

  • -Xms8g -Xmx8g -Xmn4g 改为 -Xms256m -Xmx256m -Xmn128m

img

5.启动namesrv

[root@localhost bin]# nohup sh mqnamesrv &
复制代码

6.启动broker,注意ip为公网ip,端口为navmesrv的默认端口9876

[root@localhost bin]# nohup ./mqbroker -n localhost:9876 &
复制代码

7.检查是否启动成功

[root@localhost bin]# jps -l
复制代码
  • 如果发现报错 bash: jps: 未找到命令,请更新以下命令:
[root@localhost bin]# sudo yum install java-1.8.0-openjdk-devel.x86_64
复制代码

img

  • 输入命令 jps -l

img

  • 关闭 RocketMQ 命令

./mqshutdown broker ./mqshutdown namesrv

下面我们基于Docker安装与启动RocketMQ:

Docker 启动

docker-compose.yml

注意:启动 RocketMQ Server + Broker + Console 至少需要 2G 内存

version: '3.5'
services:
  rmqnamesrv:
    image: foxiswho/rocketmq:server
    container_name: rmqnamesrv
    ports:
      - 9876:9876
    volumes:
      - ./data/logs:/opt/logs
      - ./data/store:/opt/store
    networks:
        rmq:
          aliases:
            - rmqnamesrv

  rmqbroker:
    image: foxiswho/rocketmq:broker
    container_name: rmqbroker
    ports:
      - 10909:10909
      - 10911:10911
    volumes:
      - ./data/logs:/opt/logs
      - ./data/store:/opt/store
      - ./data/brokerconf/broker.conf:/etc/rocketmq/broker.conf
    environment:
        NAMESRV_ADDR: "rmqnamesrv:9876"
        JAVA_OPTS: " -Duser.home=/opt"
        JAVA_OPT_EXT: "-server -Xms128m -Xmx128m -Xmn128m"
    command: mqbroker -c /etc/rocketmq/broker.conf
    depends_on:
      - rmqnamesrv
    networks:
      rmq:
        aliases:
          - rmqbroker

  rmqconsole:
    image: styletang/rocketmq-console-ng
    container_name: rmqconsole
    ports:
      - 8080:8080
    environment:
        JAVA_OPTS: "-Drocketmq.namesrv.addr=rmqnamesrv:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false"
    depends_on:
      - rmqnamesrv
    networks:
      rmq:
        aliases:
          - rmqconsole

networks:
  rmq:
    name: rmq
    driver: bridge
复制代码

broker.conf

RocketMQ Broker 需要一个配置文件,按照上面的 Compose 配置,我们需要在 ./data/brokerconf/ 目录下创建一个名为 broker.conf 的配置文件,内容如下:

# 所属集群名字
brokerClusterName=DefaultCluster
​
# broker 名字,注意此处不同的配置文件填写的不一样,如果在 broker-a.properties 使用: broker-a,
# 在 broker-b.properties 使用: broker-b
brokerName=broker-a
​
# 0 表示 Master,> 0 表示 Slave
brokerId=0# nameServer地址,分号分割
# namesrvAddr=rocketmq-nameserver1:9876;rocketmq-nameserver2:9876# 启动IP,如果 docker 报 com.alibaba.rocketmq.remoting.exception.RemotingConnectException: connect to <192.168.0.120:10909> failed
# 解决方式1 加上一句 producer.setVipChannelEnabled(false);,解决方式2 brokerIP1 设置宿主机IP,不要使用docker 内部IP
brokerIP1=192.168.xx.xx  #注意!!!此处要设置宿主机IP# 在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4# 是否允许 Broker 自动创建 Topic,建议线下开启,线上关闭 !!!这里仔细看是 false,false,false
autoCreateTopicEnable=true# 是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true# Broker 对外服务的监听端口
listenPort=10911# 删除文件时间点,默认凌晨4点
deleteWhen=04# 文件保留时间,默认48小时
fileReservedTime=120# commitLog 每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824# ConsumeQueue 每个文件默认存 30W 条,根据业务情况调整
mapedFileSizeConsumeQueue=300000# destroyMapedFileIntervalForcibly=120000
# redeleteHangedFileInterval=120000
# 检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
# 存储路径
# storePathRootDir=/home/ztztdata/rocketmq-all-4.1.0-incubating/store
# commitLog 存储路径
# storePathCommitLog=/home/ztztdata/rocketmq-all-4.1.0-incubating/store/commitlog
# 消费队列存储
# storePathConsumeQueue=/home/ztztdata/rocketmq-all-4.1.0-incubating/store/consumequeue
# 消息索引存储路径
# storePathIndex=/home/ztztdata/rocketmq-all-4.1.0-incubating/store/index
# checkpoint 文件存储路径
# storeCheckpoint=/home/ztztdata/rocketmq-all-4.1.0-incubating/store/checkpoint
# abort 文件存储路径
# abortFile=/home/ztztdata/rocketmq-all-4.1.0-incubating/store/abort
# 限制的消息大小
maxMessageSize=65536# flushCommitLogLeastPages=4
# flushConsumeQueueLeastPages=2
# flushCommitLogThoroughInterval=10000
# flushConsumeQueueThoroughInterval=60000# Broker 的角色
# - ASYNC_MASTER 异步复制Master
# - SYNC_MASTER 同步双写Master
# - SLAVE
brokerRole=ASYNC_MASTER
​
# 刷盘方式
# - ASYNC_FLUSH 异步刷盘
# - SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
​
# 发消息线程池数量
# sendMessageThreadPoolNums=128
# 拉消息线程池数量
# pullMessageThreadPoolNums=128
复制代码

RocketMQ 控制台

访问 http://localhost:8080 登入控制台

下面我们进行RocketMQ控制台的下载和安装,然后结合NameServer和Broker一起启动:

编译启动RocketMQ控制台

RocketMQ控制台安装,有的教程称为RocketMQ插件部署,也有的称为可视化界面(插件)搭建,含义相同

注意:最新版的RocketMQ控制台迁移到rocketmq-dashboard项目中了

编译启动rocketmq-console

旧版控制台项目rocketmq-console,下载和启动指南

原下载地址:github.com/apache/rock… ,可以从下面的截图看到,已经没有rocketmq-console子项目了:

image-20220728044119563

这是因为rocketmq控制台项目rocketmq-console项目更名为rocketmq-dashboard了,但是我们依旧可以下载到原来更名前的rocketmq-console项目,有两种方式:

  • 寻找Github其他人的fork备份;
  • 直接通过原来的release下载链接直接下载。

第一种也可以,并且以及有人构建好了只需要启动即可,地址为: rocketmq-console-ng-1.0.1.jar ;我们采用第二种方式,来下载原来的rocketmq-console项目源码进行构建,学习源码构建的原理:

下载链接:rocketmq-console-1.0.0

image-20220729012311615

可以看到原来的下载链接并没有失效,而是下载链接隐藏了。我们下载完成之后,对项目解压,然后用IDE打开项目进行修改:

1、首先修改 pom.xml 中RocketMQ版本,为对应NameServer和Broker的版本,然后等待依赖安装完成:

<rocketmq.version>4.9.2</rocketmq.version>
复制代码

2、修改springboot的配置文件 application.properties (或application.yml),指定控制台运行服务端口和NameServer实际运行地址。

# 服务端口和rocketmq连接地址
server.port: 8080
rocketmq.config.namesrvAddr=127.0.0.1:9876# 开启登录功能
rocketmq.config.loginRequired=true
 
# Dashboard文件目录,登录用户配置文件所在目录
rocketmq.config.dataPath=/tmp/rocketmq-console/data
2.确保${rocketmq.config.dataPath}定义的目录存在,并且该目录下创建登录配置文件"users.properties", 如果该目录下不存在此文件,则默认使用resources/users.properties文件。 users.properties文件格式为:
# 该文件支持热修改,即添加和修改用户时,不需要重新启动console
# 格式, 每行定义一个用户, username=password[,N]  #N是可选项,可以为0 (普通用户); 1 (管理员)  
 
#定义管理员 
admin=admin,1
 
#定义普通用户
user1=user1
user2=user2
复制代码

注意:这里如果NameSrv和Broker已经启动后,关闭RocketMQ-Dashboard的同时Broker服务也会停止,后面重启Dashboard服务会因为Broker没有启动从而导致控制台没有存储的数据的问题。

3、编译后端项目

mvn clean package -DskipTests
复制代码

编译完成后,无需启动前端front-end项目,直接运行 rocketmq-console-4.9.2.jar 即可(因为后端控制台自带前端页面)。

打开 http://localhost:8080,即可看到RocketMQ控制台界面:

image-20220729013121796

但这种方式对于最新版本的RocketMQ还是不推荐的,因为相当于这个项目已弃用(将不再支持最新的rocketmq版本),因此推荐下面这种在新的rocketmq-dashboard项目上进行源码构建的方式:

编译启动rocketmq-dashboard

新版控制台项目rocketmq-dashboard,下载和启动指南(推荐)

一开始我们也没有找到rocketmq-console子项目,直到我打开了Issues,看到Issues里也有人提出了这个问题:

参见:RocketMQ 控制台在哪里 #881

image-20220728045342297

原来是新版控制台更名为rocketmq-dashboard了,新的地址为:github.com/apache/rock…

我们可以直接下载源码或release界面下载源码zip包,然后后面进行对应rocketmq版本的控制台源码构建:

image-20220728045811053

我们下载完成后解压项目,然后使用IDE导入项目,然后和上面的步骤一样:

1、首先修改pom.xml文件中rocketmq依赖版本:

<!--        <rocketmq.version>4.9.3</rocketmq.version>-->
        <rocketmq.version>4.9.2</rocketmq.version>
复制代码

2、然后修改resource目录下的application.yml配置文件中,控制台服务端口和NameServer的连接地址的配置参数:

server:
  port: 8080 #1.rocketmq控制台服务端口号
  servlet:
    encoding:
      charset: UTF-8
      enabled: true
      force: true
## SSL setting
#  ssl:
#    key-store: classpath:rmqcngkeystore.jks
#    key-store-password: rocketmq
#    key-store-type: PKCS12
#    key-alias: rmqcngkey

spring:
  application:
    name: rocketmq-dashboard

logging:
  config: classpath:logback.xml

rocketmq:
  config:
    # if this value is empty,use env value rocketmq.config.namesrvAddr  NAMESRV_ADDR | now, default localhost:9876
    # configure multiple namesrv addresses to manage multiple different clusters
    namesrvAddrs: #2.rocketmq集群地址配置
      - 127.0.0.1:9876
      - 127.0.0.2:9876
    # if you use rocketmq version < 3.5.8, rocketmq.config.isVIPChannel should be false.default true
    isVIPChannel:
    # timeout for mqadminExt, default 5000ms
    timeoutMillis:
    # rocketmq-console's data path:dashboard/monitor
    # linux
#    dataPath: /tmp/rocketmq-console/data
    # windows
    dataPath: ./tmp/rocketmq-console/data #3.控制台临时数据存储位置配置
    # set it false if you don't want use dashboard.default true
    enableDashBoardCollect: true
    # set the message track trace topic if you don't want use the default one
    msgTrackTopicName:
    ticketKey: ticket
    # must create userInfo file: ${rocketmq.config.dataPath}/users.properties if the login is required
    loginRequired: false #4.控制台登录功能开关
    useTLS: false
    # set the accessKey and secretKey if you used acl
    accessKey: # if version > 4.4.0
    secretKey: # if version > 4.4.0

threadpool: # 5.rocketmq线程池配置
  config:
    coreSize: 10
    maxSize: 10
    keepAliveTime: 3000
    queueSize: 5000
复制代码

当然,不修改配置参数也可以(这里我们仅修改了windows下rocketmq控制台临时数据的存储位置),因为我们可以添加配置文件参数来启动项目。

注意:这里如果NameSrv和Broker已经启动后,关闭RocketMQ-Dashboard的同时Broker服务也会停止,后面重启Dashboard服务会因为Broker没有启动从而导致控制台没有存储的数据的问题。

3、编译后端项目:

mvn clean package -Dmaven.test.skip=true
复制代码

我们可以得到一个编译成功后的Jar包:

image-20220729022025416

将编译生成的Jar包复制一份到备份目录,并重命名为 rocketmq-dashboard-4.9.2.jar ,用于后续命令启动 。

4、启动编译后的rocketmq-dashboard项目:

这里有两种启动方式:第一种是本地运行项目,第二种是命令行运行部署Jar包

第一种方式:本地运行项目

本地运行的方式,优点在于方便调试项目,可以随时启动和更改代码而不用重新编译。我们点击▶️图标运行后端主启动类,即可启动rocketmq-dashboard项目:

image-20220729024048059

可以看到,项目成功启动了!因为我们没有修改配置文件中的服务端口,因此默认是运行在8080端口的。

注意:启动rocketmq-dashboard项目时,NameServer和Broker一定要保持运行状态,否则会出现连接不到端口从而启动失败。

成功启动项目后,访问 http://localhost:8080 即可看到RocketMQ运维控制台界面:

image-20220729024454119

可以看到,rocketmq-dashboard项目运行成功,并且出现了由Angular编写的前端控制台界面!

另外我们还可以注意到,项目中有一个叫做front-end的文件夹,里面是一个采用React.js编写的前端项目。虽然这个项目与项目的启动没有联系,但我们可以尝试下载依赖然后本地运行一下:

首先到 package.json 文件的根目录下,使用 npm install 安装依赖,然后使用 npm run start 运行项目:

image-20220729015827632

可以看到,前端界面打印了RocketMQ控制台中的集群信息;但是没有显示在标准控件中而是直接以文本的形式展示在页面上,说明集群功能可能会抽离到这个前端项目中显示或者前端页面将重构为React.js技术栈,总之这个项目正在完善中。

本地运行的方式测试完成了,下面测试部署包运行控制台Jar包以及添加配置参数启动控制台Jar包:

第二种方式:部署包启动

我们这里还没有重命名Jar包,等添加配置参数的测试通过了才会重命名为正式使用的Jar包名称

我们直接在IDEA中打开Terminal命令行,然后以不指定服务端口的方式直接运行部署Jar包:

java -jar target/rocketmq-dashboard-1.0.1-SNAPSHOT.jar
复制代码

image-20220729025741452

可以见到,我们以不添加配置参数的方式直接运行Jar包,项目成功运行在Tomcat默认的8080端口!

下面我们来添加启动配置参数,将部署Jar包运行在不同的端口上,通过以下命令运行启动Jar包:

java -Dserver.port=8851 -jar target/rocketmq-dashboard-1.0.1-SNAPSHOT.jar
复制代码

image-20220729030523997

可以看到,项目成功运行在8851端口。我们访问http://localhost:8851 ,可以看到控制台界面:

image-20220729030741941

启动成功,下面我们为Jar包打上Tag,并编写为Windows服务。

首先是将原来的Jar包重命名为 rocketmq-dashboard-4.9.2.jar ,然后复制到需要备份和运行的目录:

改造好的Jar包备份的目录

image-20220729031137730

注册为服务运行的目录

image-20220729031554713

注册为Windows服务

下面的启动、停止以及服务相关配置文件都是放在在同一个目录下的

1、下载 Windows Service Wrapper工具

我们也可以复制上面的WinSW.exe启动文件,重命名为rocketmq-dashboard-service.exe即可。

下载地址:github.com/winsw/winsw…

2、编写rocketmq-dashboard-service.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<service>
  <!-- 唯一服务ID-->
  <id>RocketMQ-Dashboard</id>
  <!-- 显示服务的名称 -->
  <name>RocketMQ Dashboard Service</name>
  <!-- 服务描述 -->
  <description>RocketMQ控制台服务</description>
  <!-- 日志路径 -->
  <logpath>D:\DevCenter\SpringCloudAlibaba\RocketMQ\RocketMQ Dashboard 4.9.2\logs</logpath>
  <!-- 日志模式 -->
  <logmode>roll</logmode>
  <!-- 可执行文件的命令 -->
  <executable>D:\DevCenter\SpringCloudAlibaba\RocketMQ\RocketMQ Dashboard 4.9.2\startup.cmd</executable>
  <!-- 停止可执行文件的命令 -->
  <stopexecutable>D:\DevCenter\SpringCloudAlibaba\RocketMQ\RocketMQ Dashboard 4.9.2\shutdown.cmd</stopexecutable>
</service>
复制代码

3、编写启动命令文件

创建一个startup.cmd的文件,然后输入以下内容:

java -jar rocketmq-dashboard-4.9.2.jar --server.port=8851
复制代码

@echo off 的作用是关闭回显,不显示正在执行的批处理命令及执行的结果等。这里可以不添加,因为本身就是作为注册服务的启动命令,不会出现控制台窗口。

当然,我们也有对应的静默启动的命令文件:

@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("%~nx0 h",0)(window.close)&&exit
:begin
java -jar rocketmq-dashboard-4.9.2.jar --server.port=8851
复制代码

这里为什么又添加了 @echo off 呢?这是因为静默启动的文件,是显示使用的,因此需要关闭回显输出最好。

4、编写停止命令文件

创建一个shutdown.cmd的文件,然后输入以下内容:

@echo off
setlocal
for /f "tokens=1" %%i in ('jps -m ^| find "8851"') do ( taskkill /F /PID %%i )
echo Done!
复制代码

有了启动和停止命令文件,那么我们可以注册RocketMQ控制台服务到Windows服务列表中了:

5、编写服务注册和卸载命令文件

创建一个rocketmq-dashboard-service-register.cmd的文件,添加以下内容:

@echo off
rocketmq-dashboard-service.exe install
复制代码

创建一个rocketmq-dashboard-service-uninstall.cmd的文件,添加以下内容:

@echo off
rocketmq-dashboard-service.exe uninstall
复制代码

上面的服务注册和卸载的命令文件步骤已经完成,注册服务后RocketMQ控制台程序就成为守护进程存在于Windows电脑上了,我们可以通过 services.msc 命令来查看服务列表:

image-20220729034558523

可以看到,RocketMQ的NameServer、Broker和DashBoard三大服务都以及成功注册为服务,并且都已经启动了。我们可以通过在页面访问 http://localhost:8851 来查看服务的方式启动RocketMQ控制台:

image-20220729034828027

启动成功,到此为止RocketMQ服务端的三大组件就已经启动完毕;这里因为字数限制,我们到下一篇再开始正式集成RocketMQ客户端。

欢迎点赞,谢谢各位大佬了ヾ(◍°∇°◍)ノ゙

猜你喜欢

转载自juejin.im/post/7155282562468823048