1. 获取RocketMQ源码
RocketMQ原先是阿里巴巴内部使用的消息中间件,于2017年提交到Apache基金会成为Apache基金会的顶级开源项目,GitHub代码库链接:github.com/apache/rock….在Github网站上搜索RocketMQ,如图所示.
克隆源码,命令如下
git clone github.com/apache/rock…
克隆完成后,在IntelliJ IDEA打开
导入成功后,效果如图所示
执行maven clean install 进行编译和下载依赖
下载完成后,控制台提示BUILD SUCCESS信息
2. 在IntelliJ IDEA调试RocketMQ源码
(1) 启动NameServer
- 展开namesrc模块,右键NamesrvStartup.java,移动到Debug As,选中Debug 'NamesrvStartup.java.main()'
- 点击Environment variables后面的按钮,弹出Environment variables对话框
- 点击+号,在Name输入框中输入ROCKETMQ_HOME,Value输入源码的保存路径,点击OK即可
- 在RocketMQ运行主目录创建conf、logs、store三个文件夹
- 在RocketMQ distribution部署目录中将broker.conf、logback_broker.xml文件复制到conf目录中,logback_namesrv.xml文件,只需修改日志文件的目录,brocker.conf文件目录内容代码如下所示
brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
#nameServer地址,分号分割
namesrvAddr=127.0.0.1:9876
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
# 存储路径
storePathRootDir=/rocketmq/store
# commitLog 存储路径
storePathCommitLog=/rocketmq/store/commitLog
# 消费队列存储路径
storePathConsumeQueue=/rocketmq/store/consumequeue
# 消息索引存储路径
storePathIndex=/rocketmq/store/index
# checkpoint 文件存储路径
storeCheckpoint=/rocketmq/store/checkpoint
# abort 文件存储路径
abortFile=/rocketmq/store/abort
- 在IntelliJ IDEA Debug中运行NamesrvStartup,并输出“The Name Server boot success.Serializetype=JSON”
(2) 启动Broker
-
展开broker模块,右键BrokerStartup.java执行,会提示需要配置ROCKETMQ_HOME。在idea右上角选中Debug Configurations,
在弹出的对话框中选择arguments选项,配置-c属性指定broker配置文件路径
-
切换选项卡Environment,配置ROCKETMQ_HOME主目录和broker配置文件
- 以debug模式运行BrokerStartup.java,查看${ROCKETMQ_HOME}/logs/broker.log文件,未报错则表示启动成功
(3) 使用RocketMQ提供的实例验证消息发送与消息消费
- 修改org.apache.rocketmq.example.quickstart.Producer示例程序,设置消息生产者NameServer地址
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.example.quickstart;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
/**
* This class demonstrates how to send messages to brokers using provided {@link DefaultMQProducer}.
*/
public class Producer {
public static void main(String[] args) throws MQClientException, InterruptedException {
/*
* Instantiate with a producer group name.
*/
DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
producer.setNamesrvAddr("127.0.0.1:9876");
/*
* Specify name server addresses.
* <p/>
*
* Alternatively, you may specify name server addresses via exporting environmental variable: NAMESRV_ADDR
* <pre>
* {@code
* producer.setNamesrvAddr("name-server1-ip:9876;name-server2-ip:9876");
* }
* </pre>
*/
/*
* Launch the instance.
*/
producer.start();
for (int i = 0; i < 1000; i++) {
try {
/*
* Create a message instance, specifying topic, tag and message body.
*/
Message msg = new Message("TopicTest" /* Topic */,
"TagA" /* Tag */,
("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */
);
/*
* Call send message to deliver message to one of brokers.
*/
SendResult sendResult = producer.send(msg);
/*
* There are different ways to send message, if you don't care about the send result,you can use this way
* {@code
* producer.sendOneway(msg);
* }
*/
/*
* if you want to get the send result in a synchronize way, you can use this send method
* {@code
* SendResult sendResult = producer.send(msg);
* System.out.printf("%s%n", sendResult);
* }
*/
/*
* if you want to get the send result in a asynchronize way, you can use this send method
* {@code
*
* producer.send(msg, new SendCallback() {
* @Override
* public void onSuccess(SendResult sendResult) {
* // do something
* }
*
* @Override
* public void onException(Throwable e) {
* // do something
* }
*});
*
*}
*/
System.out.printf("%s%n", sendResult);
} catch (Exception e) {
e.printStackTrace();
Thread.sleep(1000);
}
}
/*
* Shut down once the producer instance is not longer in use.
*/
producer.shutdown();
}
}
- 运行示例程序,查看运行结果,如有输出sendStatus=SEND_OK则表示消息发送成功
- 修改org.apache.rocketmq.example.quickstart.Consumer示例程序,设置消息消费者NameServer地址
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.example.quickstart;
import java.util.List;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
/**
* This example shows how to subscribe and consume messages using providing {@link DefaultMQPushConsumer}.
*/
public class Consumer {
public static void main(String[] args) throws InterruptedException, MQClientException {
/*
* Instantiate with specified consumer group name.
*/
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name_4");
consumer.setNamesrvAddr("127.0.0.1:9876");
/*
* Specify name server addresses.
* <p/>
*
* Alternatively, you may specify name server addresses via exporting environmental variable: NAMESRV_ADDR
* <pre>
* {@code
* consumer.setNamesrvAddr("name-server1-ip:9876;name-server2-ip:9876");
* }
* </pre>
*/
/*
* Specify where to start in case the specified consumer group is a brand new one.
*/
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
/*
* Subscribe one more more topics to consume.
*/
consumer.subscribe("TopicTest", "*");
/*
* Register callback to execute on arrival of messages fetched from brokers.
*/
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
ConsumeConcurrentlyContext context) {
System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
/*
* Launch the consumer instance.
*/
consumer.start();
System.out.printf("Consumer Started.%n");
}
}
- 运行消费者程序
消息发送与消息消费都成功,则说明RocketMQ调试环境已成功搭建,可以通过Debug调试源码,探索RocketMQ的奥秘了。