一、环境准备:Centos 7,jdk1.8运行环境,maven,git,未安装的可自行百度安装奥,这里就不在介绍了
二、软件包准备:
提供2种方式下载
一:直接通过官网下载bin包,解压使用
1. 下载地址:http://rocketmq.apache.org/release_notes/release-notes-4.2.0/
2. wget http://mirror.bit.edu.cn/apache/rocketmq/4.2.0/rocketmq-all-4.2.0-bin-release.zip
3. unzip rocketmq-all-4.2.0-bin-release.zip
二:通过git下载源码,自行编译打包
1. git clone https://github.com/apache/rocketmq.git
2. mvn -Prelease-all DskipTests clean install -U
3. cd distribution/target/apache-rocketmq/bin
三、启动服务
1. 启动服务器(nameserver)
2. 后台启动:nohup sh mqnamesrv &
3. 启动成功后查看jps,会出现如下显示
5189 BrokerStartup
8121 Jps
4. 启动成功后,启动broker,默认配置文件是8g奥,看自己需求配置JAVA_OPT虚拟机内存配置
vi runserver.sh
JAVA_OPT = -server -Xms2g -Xmx2g -Xmn1g
nohup sh mqbroker -n “127.0.0.1:9876" -c ../conf/2m-noslave/broker-a.properties >/dev/null &
5. 启动成功后通过jps查看进程会显示如下:
5189 BrokerStartup
8121 Jps
4796 NamesrvStartup
6. 单机已经构建完成,查看集群信息
sh mqadmin clusterList -n 127.0.0.1:9876
四、代码实例
生产者示例:
public class Producer {
public static void main(String[] args) throws MQClientException, InterruptedException {
DefaultMQProducer producer = new DefaultMQProducer("produce_group");
producer.setInstanceName("zz");
producer.setNamesrvAddr("10.211.55.5:9876"); // TODO add by yunai
producer.start();
String body = "hello:";
for (int i = 0; i < 100; i++) {
try {
String temp = body+i;
Message msg = new Message("testTopic" /* Topic */,
"*" /* Tag */,
(temp).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */
);
SendResult sendResult = producer.send(msg);
System.out.printf("%s%n", sendResult);
} catch (Exception e) {
e.printStackTrace();
Thread.sleep(1000);
}
}
producer.shutdown();
}
}
消费者示例:
public static void main(String[] args) throws InterruptedException, MQClientException {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("produce_group");
consumer.setConsumeThreadMin(1);
consumer.setConsumeThreadMax(1);
consumer.setNamesrvAddr("10.211.55.5:9876");
consumer.subscribe("testTopic", "*");
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List msgs,
ConsumeConcurrentlyContext context) {
System.out.printf(Thread.currentThread().getName() + " Receive New Messages: " + msgs + "%n");
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
System.out.println("启动第5个消费者");
System.out.printf("Consumer Started.%n");
}
消息需要制定topic,但是我们默认启动的时候是没有设置自动创建topic的,所以我们要在namesrc节点上设置我们要创建的topic:testTopic
mqadmin updateTopic -c DefaultCluster -n 127.0.0.1:9876 -t topic
创建成果后我们,可以启动生产者和消费者,开始实践啦!
五、集群模式部署
集群模式网络图如上图所示:
1、namesrv 集群模式,namesrv自身无状态,主要用来存储broker地址信息以及topic信息,生产者和消费者连接namesrv获取相应的topic信息。对于namesrv如何启动,我们可以分别在多个服务器上按照单机启动即可。
10.211.55.5 第一台机器启动namesrv
Nohup sh mqnamesrv &
10.211.55.6 第二台机器启动namesrv
nohup sh mqnamesrv &
2、broker集群模式分为:
1) 多Master-无Slave模式,搭建起来比较简单,但是一旦其中一个master节点down掉,这个节点上的数据是无法消费,影响消息的实时性。
2) 多Master-多slave异步刷盘异步同步slave模式,一个master对应多个save,其中一个master节点down掉,异步刷盘,异步同步消息到slave节点,可能会有少量的数据量丢失;消费者可送slave消费数据,消息实时性影响较低。
3) 多Master-多slave同步刷盘,与slave同步消息采用同步模式,消息不会丢失,同时实时性较好,但是同步模式大家都理解的,会降低吞吐量。
我们在这里启动多Master-多slave异步模式:如果是一台机器启动多个broker,需要在配置文件上配置不同的端口号listenPort=10911。
10.211.55.5第一台机器启动master1
Nohup sh mqbroker -n “10.211.55.5:9876” -c ../conf/2m-2s-async/broker-a.protites
10.211.55.6第二台机器启动master2
Nohup sh mqbroker -n “10.211.55.5:9876” -c ../conf/2m-2s-async/broker-b.protites
10.211.55.6启动slave1
Nohup sh mqbroker -n “10.211.55.5:9876” -c ../conf/2m-2s-async/broker-a-s.protites
10.211.55.6启动第二胎slave2
nohup sh mqbroker -n "10.211.55.5:9876" -c ../conf/2m-2s-async/broker-b-s.protites
需要注意的是,如果端口号只相对于第一个配置+1,在启动第二个broker依然会提示端口被占用,原因在于一个broker启动的是后占用多个相邻的端口,如默认是10911,会依次占用10910-10913的端口,所以我们需要指定端口跨度较大的,如10920去启动。大家有兴趣的话可以debug启动过程,后面教大家如何debug。
目前单机启动多broker,会报错
java.net.BindException: 地址已在使用
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at io.netty.channel.socket.nio.NioServerSocketChannel.doBind(NioServerSocketChannel.java:127)
at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:501)
at io.netty.channel.DefaultChannelPipeline$HeadContext.bind(DefaultChannelPipeline.java:1218)
at io.netty.channel.AbstractChannelHandlerContext.invokeBind(AbstractChannelHandlerContext.java:506)
at io.netty.channel.AbstractChannelHandlerContext.bind(AbstractChannelHandlerContext.java:491)
at io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:965)
at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:210)
at io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:353)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:408)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:455)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:140)
at java.lang.Thread.run(Thread.java:748)
OK!如果启动正常的话,可以使用mqadmin指令查看集群的运行状态,继续使用上面的生产者和消费者进行测试
sh mqadmin clusterList -n 10.211.55.5:9876
六、集群的高可用性
具体的测试步骤就不在这里阐述了,大家可以通过相关代码测试集群的不同节点down掉产生的结果,这里为大家准备一张表格可以更直观的理解:
发送消息 | 发送消息过程 | 接收消息 | |
---|---|---|---|
停用一个namesrv | 不影响 | 不影响 | 不影响 |
全部停用namesrv | 影响通信 | 不影响 | y影响消费,恢复任意一个则恢复 |
停用一个master | 不影响 | 不影响 | 不影响 |
停用一个slave | 不影响 | 不影响 | 不影响 |
全部停用master | 影响 | 影响,数据丢失 | 影响 |
恢复一个master | 不影响 | 发送中影响,数秒恢复 | 不影响,数秒恢复 |
附上broker配置参数:
#所属集群名字
brokerClusterName=rocketmq-cluster
#broker名字,注意此处不同的配置文件填写的不一样
brokerName=broker-a|broker-b
#0 表示 Master,>0 表示 Slave
brokerId=0
#nameServer地址,分号分割
namesrvAddr=192.168.1.101:9876;192.168.1.102:9876
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
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=/usr/local/alibaba-rocketmq/store
#commitLog 存储路径
storePathCommitLog=/usr/local/alibaba-rocketmq/store/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/usr/local/alibaba-rocketmq/store/consumequeue
#消息索引存储路径
storePathIndex=/usr/local/alibaba-rocketmq/store/index
#checkpoint 文件存储路径
storeCheckpoint=/usr/local/alibaba-rocketmq/store/checkpoint
#abort 文件存储路径
abortFile=/usr/local/alibaba-rocketmq/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
#checkTransactionMessageEnable=false
#发消息线程池数量
#sendMessageThreadPoolNums=128
#拉消息线程池数量
#pullMessageThreadPoolNums=128
上述有什么不对的地方,欢迎指正!