linux 本地安装 rocketmq
(本人是centos7)
一、首先需要安装jdk
自行处理,安装好后检查环境变量是否配置了
(本人安装的是jdk21,版本还是挺高的)
二、安装RocketMQ
1、快速搭建RocketMQ服务
(本人安装的是rocketmq5.3.1)
RocketMQ的官网地址
在下载页面可以获取RocketMQ的源码包以及运行包。
下载页面地址
下载页面地址中文版
关于RocketMQ的版本: 我们这里采用最新的5.3.0版本。
注:在2022年下半年,RocketMQ新推出了5.0的大版本,这对于RocketMQ来说,是一个里程碑式的大版本。在这个大版本中,RocketMQ对整体功能做了一次大的升级。增加了很多非常有用的新特性,也对已有功能重新做了升级。据传,RocketMQ从4.x版本升级到5.x版本,重构的代码量超过了60%,变化是非常大的。另外,你可能要注意一下,4.x的系列版本已经于2024年3月停止了维护。这意味着目前已经不建议使用4.x的版本了。
运行只需要下载Binary运行版本就可以了。下载下来后,就可以直接解压,上传到服务器上。我们这里会上传到/app/rocketmq目录。解压后几个重要的目录如下:
- 1.修改 runserver.sh 、 runbroker.sh 配置文件
默认情况下,RocketMQ建议的运行环境需要至少12G的内存,这是生产环境比较理想的资源配置。但是,学习阶段,如果你的服务器没有这么大的内存空间,那么就需要做一下调整。进入bin目录,对其中的runserver.sh和runbroker.sh两个脚本进行一下修改。
使用vi runserver.sh指令,编辑这个脚本,找到下面的一行配置,调整Java进程的内存大小。
自己看着修改,我的截图放在下面了,就是调小一点
JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=90m -
XX:MaxMetaspaceSize=180m"
注:上面有一行注释,java9以前的就改if后面的配置,如果是java9以后的那么就改else里面的配置
接下来,同样调整runbroker.sh中的内存大小。
JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g"
自己看着修改,我的截图放在下面了,就是调小一点
修改为:
JAVA_OPT="${JAVA_OPT} -server -Xms2g -Xmx2g"
修改配置时,注意要根据你的JDK版本调整对应的配置行。RocketMQ是一个典型的Java应用,所以需要提前安装JDK。我们这里采用的是21版本。JDK的安装过程略。生产环境不建议调整。这一系列参数实际上就是RocketMQ的JVM调优结果。
RocketMQ的后端服务分为nameserver和broker两个服务,这两个服务都需要启起来。
还有一个需要注意,我当时在启动broker的时候他给我报下面这个错误,意思是:
Unrecognized VM option ‘UseBiasedLocking’ 意味着你试图启动 Java 虚拟机时,遇到了一些不兼容的 JVM 参数。UseBiasedLocking 是一个参数,用于启用和禁用锁的偏向性机制,以减少锁争用的开销,但在一些较新的 Java 版本(如 Java 21)中被移除。由于 RocketMQ 使用的 JVM 版本可能不再支持这个参数,导致启动失败。
Unrecognized VM option 'UseBiasedLocking'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
解决办法:
(前提java环境变量一定要配置好,自己可以 java -version 看一下)
1.打开 runbroker.sh 和 runserver.sh(位于 ROCKETMQ_HOME/bin 目录下)。
2.找到并删除或注释掉 -XX:+UseBiasedLocking 参数。(只删除-XX:+UseBiasedLocking,不要整行都删)
3.实在不行就换jdk版本吧
进入vim 然后英文 / ,输入 UseBiasedLocking 按回车,我当时是只删一个文件里面的UseBiasedLocking。
- 2.配置rocketmq环境变量
注:1、在实际服务部署时,通常会将RocketMQ的部署地址添加到环境变量当中。例如使用vi:
vim /etc/profile
到末尾添加如下代码
export ROCKETMQ_HOME=/app/rocketmq/rocketmq-all-5.3.0-bin-release
export PATH=$ROCKETMQ_HOME/bin:$PATH
添加完环境变量刷一下代码如下
source /etc/profile
这样就不必每次进入RocketMQ的安装目录了。直接可以使用mqnamesrv 和mqbroker指令。
- 3.启动nameserver服务
cd /app/rocketmq/rocketmq-all-5.3.0-bin-release
nohup bin/mqnamesrv &
或者
nohup sh mqnamesrv &
指令执行后,会生成一个nohup.out的日志文件。在这个日志文件里如果看到下面这一条关键日志,就表示nameserver服务启动成功了。 less nohup.out 查看日志
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, address 0.0.0.0:9876
接下来,可以通过jsp指令进行验证。使用jps指令后,可以看到有一个NamesrvStartup的进程运行,也表示nameserver服务启动完成。
- 4.启动broker服务
broker也是一个Java服务,只需要调整conf目录下的broker.conf文件,进行一些定制。然后就可以启动了。
具体配置项参见官方文档,这里尽量走默认配置。
如果你的服务器配置了多张网卡,建议配置brokerIP1属性。比如阿里云,腾讯云这样的云服务器,他们通常有内网网卡和外网网卡两张网卡,那么需要增加配置brokerIP1属性,指向服务器的外网IP 地址,这样才能确保从其他服务器上访问到RocketMQ 服务。
在启动broker服务前,需要先指定NameServer的服务地址。RocketMQ可以使用一个NAMESRV_ADDR的环境变量指定NameServer服务地址。
通过vi /etc/profile添加以下配置。然后使用source /etc/profile让配置生效。
export NAMESRV_ADDR='localhost:9876'
9876是nameserver的默认服务端口。
然后也可以用之前的方式启动broker服务。启动broker服务的指令是mqbroker。
cd /app/rocketmq/rocketmq-all-5.3.0-bin-release
nohup bin/mqbroker &
停止RocketMQ服务可以通过mqshutdown指令进行
mqshutdown namesrv # 关闭nameserver服务
mqshutdown broker # 关闭broker服务
启动完成后,同样检查nohup.out日志文件,有如下一条关键日志,就表示broker服务启动正常了。 less nohup.out 查看日志。
The broker[xxxxx] boot success. serializeType=JSON and name server is localhost:9876
2、快速实现消息收发
RocketMQ后端服务启动完成后,就可以启动客户端的消息生产者和消息消费者进行消息转发了。接下来,我们会先通过RocketMQ提供的命令行工具快速体验一下RocketMQ消息收发的功能。然后,再动手搭建一个Maven项目,在项目中使用RocketMQ进行消息收发。
- 1.命令行快速实现消息收发
1》:通过指令启动RocketMQ的消息生产者发送消息。
cd /app/rocketmq/rocketmq-all-5.3.0-bin-release
bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
这个指令会默认往RocketMQ中发送1000条消息。在命令行窗口可以看到发送消息的日志:
.....
SendResult [sendStatus=SEND_OK, msgId=C0A841708122246B179D98C9E31103E6,
offsetMsgId=C0A8417000002A9F000000000003AEFE, messageQueue=MessageQueue [topic=TopicTest,
brokerName=192-168-65-112, queueId=1], queueOffset=249]
SendResult [sendStatus=SEND_OK, msgId=C0A841708122246B179D98C9E31203E7,
offsetMsgId=C0A8417000002A9F000000000003AFF0, messageQueue=MessageQueue [topic=TopicTest,
brokerName=192-168-65-112, queueId=2], queueOffset=249]
这部分日志中,并没有打印出发送了什么消息。上面SendResult开头部分是消息发送到Broker后的结果。最后两行日志表示消息生产者发完消息后,服务正常关闭了。
2》:可以启动消息消费者接收之前发送的消息
bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
消费者启动完成后,可以看到消费到的消息
......
ConsumeMessageThread_please_rename_unique_group_name_4_18 Receive New Messages:
[MessageExt [brokerName=192-168-65-112, queueId=1, storeSize=242, queueOffset=211,
sysFlag=0, bornTimestamp=1725004967502, bornHost=/192.168.65.112:52748,
storeTimestamp=1725004967502, storeHost=/192.168.65.112:10911,
msgId=C0A8417000002A9F0000000000031F4E, commitLogOffset=204622, bodyCRC=47888112,
reconsumeTimes=0, preparedTransactionOffset=0, toString()=Message{topic='TopicTest',
flag=0, properties={CONSUME_START_TIME=1725005058184, MSG_REGION=DefaultRegion,
UNIQ_KEY=C0A841708122246B179D98C9E24E034E, CLUSTER=DefaultCluster, MIN_OFFSET=0,
TAGS=TagA, WAIT=true, TRACE_ON=true, MAX_OFFSET=250}, body=[72, 101, 108, 108, 111, 32,
82, 111, 99, 107, 101, 116, 77, 81, 32, 56, 52, 54], transactionId='null'}]]
每一条这样的日志信息就表示消费者接收到了一条消息。这个Consumer消费者的指令并不会主动结束,他会继续挂起,等待消费新的消息。我们可以使用CTRL+C停止该进程。
注:在RocketMQ提供的这个简单示例中并没有打印出传递的消息内容,而是打印出了消息相关的很多重要的属性。其中有几个比较重要的属性:brokerId,brokerName,queueId,msgId,topic,cluster。这些属性的作用会在后续一起分享,这里你不妨先找一下这些属性是什么,消费者与生产者之间有什么样的对应关系。
3、搭建Java客户端项目
之前的步骤实际上是在服务器上快速验证RocketMQ的服务状态,接下来我们动手搭建一个RocketMQ的客户端应用,在实际应用中集成使用RocketMQ。
- 第一步 :创建一个标准的maven项目,在pom.xml中引入以下核心依赖
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>5.3.0</version>
</dependency>
- 第二步:就可以直接创建一个简单的消息生产者
public class Producer {
public static void main(String[] args) throws MQClientException, InterruptedException
{
//初始化一个消息生产者
DefaultMQProducer producer = new DefaultMQProducer("DemoProducer");
// 指定nameserver地址
producer.setNamesrvAddr("192.168.108.130:9876");
// 启动消息生产者服务
producer.start();
for (int i = 0; i < 2; i++) {
try {
// 创建消息。消息由Topic,Tag和body三个属性组成,其中Body就是消息内容
Message msg = new Message("TopicTest","TagA",("Hello RocketMQ
" +i).getBytes(RemotingHelper.DEFAULT_CHARSET));
//发送消息,获取发送结果
SendResult sendResult = producer.send(msg);
System.out.printf("%s%n", sendResult);
} catch (Exception e) {
e.printStackTrace();
Thread.sleep(1000);
}
}
//消息发送完后,停止消息生产者服务。
producer.shutdown();
}
}
运行其中的main方法,就会往RocketMQ中发送两条消息。在这个实现过程中,需要注意一下的是对于生产者,需要指定对应的nameserver服务的地址,这个地址需要指向你自己的服务器。
- 第三步:创建一个消息消费者接收RocketMQ中的消息
public class Consumer {
public static void main(String[] args) throws InterruptedException, MQClientException
{
//构建一个消息消费者
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("DemoConsumer");
//指定nameserver地址
consumer.setNamesrvAddr("192.168.108.130:9876");
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
// 订阅一个感兴趣的话题,这个话题需要与消息的topic一致
consumer.subscribe("TopicTest", "*");
// 注册一个消息回调函数,消费到消息后就会触发回调。
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt>
msgs,ConsumeConcurrentlyContext context) {
msgs.forEach(messageExt -> {
try {
System.out.println("收到消息:"+new String(messageExt.getBody(),
RemotingHelper.DEFAULT_CHARSET));
} catch (UnsupportedEncodingException e) {}
});
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
//启动消费者服务
consumer.start();
System.out.print("Consumer Started");
}
}
运行其中的main方法后,就可以启动一个RocketMQ消费者,接收之前发到RocketMQ上的消息,并将消息内容打印出来。在这个实现过程中,需要重点关注的有两点。一是对于消费者,同样需要指定nameserver的地址。二是消费者需要在RocketMQ中订阅具体的Topic,只有发送到这个Topic上的消息才会被这个消费者接收到。
示例代码不用强行记忆, 在RocketMQ的源码包中有个example模块,其中就有这些示例代码。
这样,通过几个简单的步骤,我们就完成了RocketMQ的应用集成。从这个过程中可以看到,RocketMQ的使用是比较简单的。但是这并不意味着这几个简单的步骤就足够搭建一个生产级别的RocketMQ服务。接下来,我们会一步步把我们这个简单的RocketMQ服务往一个生产级别的服务集群推进。
三、搭建RocketMQ可视化管理服务
在之前的简单实验中,RocketMQ都是以后台服务的方式在运行,我们并不很清楚RocketMQ是如何运行的。RocketMQ的社区就提供了一个图形化的管理控制台Dashboard,可以用可视化的方式直接观测并管理RocketMQ的运行过程。Dashboard服务并不在RocketMQ的运行包中,需要到RocketMQ的官网下载页面单独下载。
这里只提供了源码,并没有提供直接运行的jar包。将源码下载下来后,需要解压并进入对应的目录,使用maven进行编译。(需要提前安装maven客户端)
mvn clean package -Dmaven.test.skip=true
编译完成后,在源码的target目录下会生成可运行的jar包rocketmq-dashboard-1.0.1-SNAPSHOT.jar。接下来可以将这个jar包上传到服务器上。我们上传到/app/rocketmq/rocketmq-dashboard目录下,接下来我们需要在jar包所在的目录下创建一个application.yml配置文件,在配置文件中做如下配置:
rocketmq:
config:
namesrvAddrs:
- 192.168.108.130:9876
主要是要指定nameserver的地址。
注:关于这个配置文件中更多的配置选项,可以参考一下dashboard源码当中的application.yml配置文件。
接下来就可以通过java指令执行这个jar包,启动管理控制台服务。
java -jar rocketmq-dashboard-1.0.1-SNAPSHOT.jar 1>dashboard.log 2>&1 &
应用启动完成后,会在服务器上搭建起一个web服务,我们就可以通过访问http://192.168.108.130:8080 查看到管理页面
这个管理控制台的功能非常全面。驾驶舱页面展示RocketMQ近期的运行情况。运维页面主要是管理nameserver服务。集群页面主要管理RocketMQ的broker服务。很多信息都一目了然。在之后的过程中,我们也会逐渐了解DashBoard管理页面中更多的细节。