文档下载地址:https://download.csdn.net/download/u012246342/11069364
文档包含:
Rocket MQ 的下载地址:https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.4.0/rocketmq-all-4.4.0-source-release.zip
默认的配置文件在 rocketmq-all-4.4.0-bin-release\conf 下。
在 MQ 启动之后,安装控制台并启动之后,在 控制台的 集群页面,可以看见集群的配置,
在当前配置文件中,可以进行一系列 配置。简略版(29服务器配置)配置如下:
brokerClusterName = SPZC_MQ_Cluster
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
namesrvAddr=192.168.10.29:9876
listenPort=10921
brokerIP1=192.168.10.29
defaultTopicQueueNums=4
autoCreateTopicEnable=true
autoCreateSubscriptionGroup=true
27服务器配置如下:
brokerClusterName = SPZC_MQ_Cluster
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
namesrvAddr=192.168.10.27:9876
listenPort=10921
brokerIP1=192.168.10.27
storePathRootDir=/opt/rocketmq/broker-a-m/rootdir
storePathCommitLog=/opt/rocketmq/broker-a-m/commitlog
defaultTopicQueueNums=4
autoCreateTopicEnable=true
autoCreateSubscriptionGroup=true
其中,27 比29 多的两个配置 是,设置 存储路径。storePathRootDir 和 storePathCommitLog 如果没有进行设置,则 默认的 存储路径为 :/root/store
在rocketMQ 的源码中,配置 以及描述 主要包含在 下面几个文件中:
其中,比较关键的配置如下:
# 默认消息长度 4M Maximum allowed message size in bytes.
maxMessageSize = 1024 * 1024 * 4
# 默认消息保存时间 3天 The number of hours to keep a log file before deleting it (in hours)
fileReservedTime = 72
# 默认删除消息执行时间,凌晨4点 When to delete,default is at 4 am
deleteWhen = "04"
# 默认队列 4 Number of queues to create per default topic.
defaultTopicQueueNums = 4
# 默认 保存文件的大小,1G CommitLog file size,default is 1G
mapedFileSizeCommitLog = 1024 * 1024 * 1024
# 默认保存数据 30万条 ConsumeQueue file size,default is 30W
mapedFileSizeConsumeQueue = 300000 * ConsumeQueue.CQ_STORE_UNIT_SIZE
#保存路径 The root directory in which the log data is kept
storePathRootDir=/root/store
# commitlog保存路径 The directory in which the commitlog is kept
storePathCommitLog = /root/store/commitlog
# 是否允许自动创建topic
autoCreateTopicEnable = true
首先,必须有 JDK。
默认的MQ 启动内存设置较大,需要先修改启动内存,对应文件如下:
JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g"
JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
1、启动 nameServer
nohup sh /home/fan/java/rocketmq-all-4.3.2-bin-release/bin/mqnamesrv >/dev/null 2>&1 &
2、启动 broker
nohup sh /home/fan/java/rocketmq-all-4.3.2-bin-release/bin/mqbroker -c /home/fan/java/rocketmq-all-4.3.2-bin-release/conf/broker.conf >/dev/null 2>&1 &
3、启动控制台
nohup java -jar rocketmq-console-ng-1.0.0.jar &
4、查看是否启动成功
jps
__当 jsp 命令,可以看到 如下结果,说明启动成功 __
root@spzc:/home/fan/java# jps
13760 Jps
3361 jar
3253 NamesrvStartup
3278 BrokerStartup
root@spzc:/home/fan/java#
5、结束进程(结束MQ控制台 对应的进程)
kill -9 3361
控制台 代码下载地址:https://github.com/apache/rocketmq-externals
从 这个地址下载 整个项目代码.
到 /rocketmq-externals-master 的 /rocketmq-console 项目 目录下。可以看到,当前目录,就是 mq 的 console 项目根目录。
打开 ./src/main/resources , 修改 application.properties 配置文件。
修改 可以 修改端口,默认是 8080
server.contextPath=192.168.10.27(对应的 IP)
server.port=8080
rocketmq.config.namesrvAddr=192.168.10.27:9876
这三条值,改为对应的 IP 和端口。
切换到 项目根目录, 在 当前目录下运行命令 mvn package
即可 在 target 目录下,找到 对应的 jar.
使用 下面命令启动控制台。
nohup java -jar rocketmq-console-ng-1.0.0.jar &
控制台的访问端口 是 默认的 8080 ,可以通过 上面 配置 修改端口
按照重要性排序
类似概念这种东西,我就直接复制网上的了。(其他的都是自己手打的。)
1、阿里云官方文档:订阅关系一致
消息队列 RocketMQ 里的一个消费者 Group ID 代表一个 Consumer 实例群组。 对于大多数分布式应用来说,一个消费者 Group ID 下通常会挂载多个 Consumer 实例。 订阅关系一致指的是同一个消费者 Group ID 下所有 Consumer 实例的处理逻辑必须完全一致。 一旦订阅关系不一致,消息消费的逻辑就会混乱,甚至导致消息丢失。
由于消息队列 RocketMQ 的订阅关系主要由 Topic+Tag 共同组成,因此,保持订阅关系一致意味着同一个消费者 Group ID 下所有的实例需在以下两方面均保持一致:
订阅的 Topic 必须一致;
订阅的 Topic 中的 Tag 必须一致。
这是分割线
2、阿里云官方文档:集群消费和广播消费
消息队列 RocketMQ 是基于发布/订阅模型的消息系统。消息的订阅方订阅关注的 Topic,以获取并消费消息。由于订阅方应用一般是分布式系统,以集群方式部署有多台机器。因此消息队列 RocketMQ 约定以下概念。
集群:使用相同 Group ID 的订阅者属于同一个集群。同一个集群下的订阅者消费逻辑必须完全一致(包括 Tag 的使用),这些订阅者在逻辑上可以认为是一个消费节点。
集群消费:当使用集群消费模式时,消息队列 RocketMQ 认为任意一条消息只需要被集群内的任意一个消费者处理即可。
广播消费:当使用广播消费模式时,消息队列 RocketMQ 会将每条消息推送给集群内所有注册过的客户端,保证消息至少被每台机器消费一次。
这是分割线
3、其他人的博客(不保证正确性,仅供参考):RocketMQ原理(2)——核心概念及术语
这是分割线
4、其他人的博客(不保证正确性,仅供参考):RocketMQ(5)——消息文件过期原理
创建 topic 有 3种方式。
Topic列表页
消息发送页
消息发送状态
查看消息列表页
查看消息详情页
下面是 生产者,消费者,和 各自启动类的示范代码
Produce
package rocketmq;
import java.util.UUID;
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;
public class TestProducer {
DefaultMQProducer defProducer = new DefaultMQProducer();
private String addrs;
public String getAddrs() {
return addrs;
}
public void init(String addrs, String groupName, String instanceName)
throws MQClientException, InterruptedException {
this.addrs = addrs;
/**
* 一个应用创建一个Producer,由应用来维护此对象,可以设置为全局对象或者单例
* 注意:ProducerGroupName需要由应用来保证唯一
* ProducerGroup这个概念发送普通的消息时,作用不大,但是发送分布式事务消息时,比较关键,
* 因为服务器会回查这个Group下的任意一个Producer
*/
defProducer.setProducerGroup(groupName);
defProducer.setNamesrvAddr(addrs);// "192.168.1.133:9876"
defProducer.setInstanceName(instanceName);// "Producer"
defProducer.setVipChannelEnabled(false);
start();
// createTopic("%RETRY%RouteGroup", routeRegisteTopic, 6);//初始化 MQ 时,会
// 直接 创建 路由 topic
// createTopic("%RETRY%RouteGroup", rpcTopic, 6);//初始化 MQ 时,会 直接 创建 rpc
// 通讯 topic
// createTopic("%RETRY%RouteGroup", noticeSCTopic, 6);//初始化 MQ 时,会 直接 创建
// rpc 通讯 topic
}
public void createTopic(String key, String newTopic, int queueNum) {
try {
defProducer.createTopic(key, newTopic, queueNum);
} catch (MQClientException e) {
e.printStackTrace();
}
}
public void sendMsg(String topic, String tag, String key, String msgBody) {
try {
//
key = "".equals(key) ? UUID.randomUUID().toString()
.replaceAll("-", "") : key;
Message msg = new Message(topic,// topic
tag,// tag
key,// key
msgBody.getBytes(RemotingHelper.DEFAULT_CHARSET));// body
SendResult sendResult = defProducer.send(msg);
int sendCode = sendResult.getSendStatus().hashCode();
System.out.println("本地发送 服务 给远程 :" + key + " , mes :" + msgBody
+ ", sendCode = " + sendCode);
} catch (Exception e) {
e.printStackTrace();
}
}
public void start() throws MQClientException {
defProducer.start();
}
public void stop() {
defProducer.shutdown();
}
}
启动类
package rocketmq;
import org.apache.rocketmq.client.exception.MQClientException;
public class TestSend {
public static void main(String[] args) {
try {
TestProducer produce = new TestProducer();
produce.init("192.168.0.112:9876", "test" + "RpcGroupName", "test"+ "RpcInstanceName");
produce.sendMsg("testTopic", "testTag", "random ID", "messageBody");
} catch (MQClientException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Consumer
package rocketmq.consumer;
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.message.MessageExt;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
/**
*
* @author Administrator
*
*/
public class TestConsumer {
protected final String encoding = "UTF-8";
DefaultMQPushConsumer defConsumer = new DefaultMQPushConsumer();
/**
* 初始化消费者 , 消费者 初始化 之后,会监听 路由 topic 的 两个 tag ,分别 是,1、注册路由 会 将 消息中 的路由信息 保存到
* 数据库 中 2、 请求路由。 会将 最新的 路由文件 发送到 请求的 rpc 容器中。
*
* @param groupName
* 消费者 组名
* @param addrs
* 地址
* @param name
* 名称
* @throws InterruptedException
* @throws MQClientException
*/
public void init(String groupName, String addrs, String instanceName,
String topic, String tag)
throws InterruptedException, MQClientException {
defConsumer.setConsumerGroup(groupName);// "ConsumerGroupName"
defConsumer.setNamesrvAddr(addrs);// "192.168.1.133:9876"
defConsumer.setInstanceName(instanceName);// "Consumber"
defConsumer.setMessageModel(MessageModel.CLUSTERING);// 設置集群模式
// 1、 订阅 当前 topic 消息 并且 tag 。
defConsumer.subscribe(topic, tag);
defConsumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(
List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
MessageExt msg = msgs.get(0);
if (msg.getTopic().equals(topic)) {
/**
* 获取 所有的 RPC调用 ,只做 保存记录用
*/
try {
String msgEntity = new String(msg.getBody(), encoding); // String
// 格式的
// json
// JSONObject jsonMsg =
// JSONObject.parseObject(msgEntity);
System.out.println("*********1111111111111111**********");
System.out.println("唉,我还是被执行了,我接收到的数据是:" + msgEntity);
} catch (Exception e) {
e.printStackTrace();
}
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
start();
}
public void start() throws MQClientException {
defConsumer.start();
}
public void stop() {
defConsumer.shutdown();
}
}
启动类
package rocketmq;
import org.apache.rocketmq.client.exception.MQClientException;
import rocketmq.consumer.TestConsumer;
public class TestOnMessage {
public static void main(String[] args) {
try {
TestConsumer consumerInit = new TestConsumer();
consumerInit.init("test"+"RpcGroupName", "192.168.0.112:9876", "test"+"RpcInstanceName1", "testTopic", "testTag");
} catch (MQClientException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}