目录
初识RocketMQ
1、消息队列
2、消息队列的应用场景
3、RocketMQ的简介
4、各类MQ的对比
5、RocketMQ的技术架构
6、RockerMQ领域模型
1. 消息生产
2. 消息存储
3. 消息消费
Docker部署单机RocketMQ
1. 前言
2. 拉取镜像
3. 下载可视化工具镜像
4. broker配置
5.启动文件 rocketmq.yml 配置
6. 测试消息的发送和接收
首先,在pom.xml文件中添加RocketMQ的依赖:
RocketMQ集群搭建
一、集群特点
二、服务器环境
1.1.部署架构
1.2.服务器信息
1.3.配置Host (两台服务器都需要)
1.4. 安装jdk(两台服务器都需要)
1.5. 关闭防火墙(两台服务器都需要)
1.6. 创建数据存储目录(两台服务器都需要)
三、下载与安装配置
2.1.下载rocketmq并解压(两天服务器都要)
2.2. 环境变量配置(两台服务器都需要)
2.3. 配置 rocketmq broker-a (在Master1上操作)
2.4. 配置 rocketmq broker-b-s (在Slave2上配置)
2.5. 配置 rocketmq broker-b.properties(在Master2上操作)
2.6. 配置rocketmq broker-a-s.properties(在Slave1上操作)
2.7. 测试环境JVM配置(两台机器都要执行)
2.8. 生产环境JVM配置
四、启动集群
3.1.启动nameserver((两台机器上都执行)
3.2.启动broker
3.3.测试集群生产消费情况
3.5. 关闭命令
五、问题总结
六、安装管理面板
初识RocketMQ
1、消息队列
消息队列(Message Queue,下面简称MQ) 是一种用于分布式系统中各节点之间进行消息传输的,独立于平台的软件系统。如果把分布式系统中的各个节点比喻成商家和顾客的话,那么消息中间件就是快递公司。商家(生产者)将快递(消息)投递给快递公司,快递公司负责运送快递给顾客(消费者)。那么在分布式系统架构中为啥要用消息中间件呢?
2、消息队列的应用场景
消息队列在分布式系统中主要用于异步解耦,流量削峰等场景。就以订单流程为例。没有使用消息队列的情况下,用户下单,需要订单系统调用商品系统扣减库存,调用积分系统发放积分,调用优惠券系统抵扣优惠券。这几个系统都与订单系统耦合在一块了。任意一个系统的失败都可能导致下单失败。
使用消息队列之后,订单系统只需要发送一条消息,商品系统,积分系统,优惠券系统直接订阅订单系统发送的消息即可。
3、RocketMQ的简介
RocketMQ是阿里巴巴开源的一款消息队列,它具有低延迟,高吞吐量,高可靠性等特点。目前,RocketMQ在阿里巴巴内部有着广泛的应用,经历多次双十一的洗礼,RocketMQ的可靠性非常高。
4、各类MQ的对比
目前市面上常用的MQ有: kafka, RabbitMQ,RocketMQ,ActiveMQ。这四种MQ的主要对比如下图所示:
名称 | RabbitMQ | ActiveMQ | RocketMQ | kafka |
开发语言 | Erlang | Java | Java | Scala&Java |
客户端支持语言 | 支持,JAVA优先 | 语言无关 | 只支持JAVA | 支持,JAVA优先 |
单机吞吐量 | 其次(万级) | 最差(万级) | 最高(十万级) | 次之(十万级) |
消息延迟 | 微秒级 | \ | 比kafka快 | 毫秒级 |
数据可靠性 | 可以保证数据不丢失,有slave用作备份 | master/slave | 支持异步实时刷盘,同步刷盘,同步复制,异步复制 | 数据可靠,并且有副本机制,有容错容灾能力 |
HA | master/slave模式,master提供服务,slave仅作备份 | 基于Zookeeper+LevelDB的Master-Slave实现方式 | 支持多Master模式,多Master多Slave模式,异步复制模式, | 支持replica机制,leader宕机后,备份自动顶替,并重新选举leader(基于zookeeper) |
消息推拉模式 | 多协议,Pull/Push均有支持 | 多协议,Pull/Push均有支持 | 多协议,Pull/Push均有支持 | Pull |
成熟度 | 成熟 | 成熟 | 比较成熟 | 成熟 |
特点 | ||||
支持协议 | 多协议支持:AMQP,XMPP,SMTP,STOMP | 自有协议 | 自有协议,社区封装了HTTP协议支持 | |
持久化 | 内存,文件,支持数据堆积,但数据堆积会影响生产速率 | 内存,文件,数据库 | 磁盘文件 | 磁盘文件,只要做到 |
事务 | 不支持 | 支持 | 支持 | 不支持,但可以通过Low Level API保证只消费一次 |
负载均衡 | 支持 | 支持 | 支持 | 支持 |
集群 | 支持 | 支持 | 支持 | 支持 |
评价 | 优点:由于Erlang语言的特性,mq性能较好,管理界面丰富,在互联网公司也有大规模应用;支持amqp。 缺点:erlang语言难度较大,集群不支持动态扩展。 | 优点:成熟的产品,已经在很多公司得到应用。缺点:社区不活跃,会出现莫名其妙的问题,且会丢失消息 | 优点:模型简单。在阿里大规模应用,单日处理消息上百亿。 |
综上所述:
早期的话ActiveMQ使用比较多,但是ActiveMQ没有经历过大吞吐量场景的验证,且可能会丢失消息,社区也不活跃,现在应用的比较少了。
RabbitMQ 得益于其活跃的开源社区以及高可用性被不少公司应用。但是Erlang语言阻止了大量的java开发工程师去深入研究和掌握它,对公司而言,几乎处于不可控的状态。
RocketMQ 作为经历过双十一大吞吐量场景的考验,Java语言开发的消息队列,现在被越来越多的公司采用。RocketMQ也已经捐给了Apache 基金会,社区较为活跃。
kafka主要应用于日志收集场景。
如果系统使用消息队列主要场景是处理在线业务,比如在交易系统中用消息队列传递订单,需要低延迟和高稳定性,建议使用 RocketMQ。
如果需要处理海量的消息,像收集日志、监控信息或是埋点这类数据,或是你的应用场景大量使用了大数据、流计算相关的开源产品,那 Kafka 是最适合的消息队列。
5、RocketMQ的技术架构
RockerMQ架构上主要分为四部分, 如上图所示:
- Producer: 消息生产者角色,支持分布式集群部署,主要用于发送消息,通常集成于业务系统。它相当于是发信者。
- Consumer: 消息消费者角色,支持分布式集群部署,支持以push推,pull拉两种模式对消息进行消费。同时也支持集群方式和广播方式的消费,通常集成于业务系统。它相当于收信者。
- Broker: 主要负责消息的存储、投递和查询以及服务高可用保证。它相当于是邮局 其内部包含以下几个重要子模块。
4.1. Remoting Module: 整个Broker的实体,负责处理来自Clients端的请求。
4.2. Client Manager: 负责管理客户端(Producer/Consumer)和维护Topic订阅信息。
4.3. Store Service: 提供方便简单的API接口处理消息存储到物理磁盘和查询功能。 - NameServer: 它是Broker的注册中心,支持Broker的动态注册与发现。它主要包括两个功能:Broker管理,NameServer接受Broker集群的注册信息并且保存下来作为路由信息的提供者。然后提供心跳检测机制,检查Broker是否存活;路由信息管理,每个NameServer通常也是集群方式部署,各实例互不进行通信,Broker向每一台NameServer注册自己的路由信息, 所以,每一个NameServer实例上面都保存一份完整的路由信息,当某个NameServer因某种原因下线了,Broker仍然可以向其他NameServer同步其路由信息。NameServer是无状态的。
6、RockerMQ领域模型
如上图所示,RocketMQ中消息的生命周期主要分为消息生产、消息存储、消息消费这三部分。
生产者生产消息并发送到RocketMQ服务端,消息被存储到服务端的主题中,消费者通过订阅主题消费消息。
1. 消息生产
生产者(Producer):用于产生消息的运行实体,一般集成于业务调用链路的上游。生产者是轻量级匿名无身份的。
2. 消息存储
- 主题(Topic):
RocketMQ 消息传输和存储的分组容器,主题内部由多个队列组成,消息的存储和水平扩展实际是通过主题内的队列实现的。 - 队列(MessageQueue):
RocketMQ 消息传输和存储的实际单元容器,类比于其他消息队列中的分区。RocketMQ 通过流式特性的无限队列结构来存储消息,消息在队列内具有顺序存储特性。 - 消息(Message):
RocketMQ 的最小传输单元,消息具备不可变性,在初始化发送和完成存储后即不可变。
3. 消息消费
- 消费者分组(ConsumerGroup):
RocketMQ发布订阅模型中定义的独立的消费身份分组。用于统一管理底层运行的多个消费者(Consumer)。同一个消费者组的多个消费者必须保持消费逻辑和配置一致,共同分担该消费者组订阅的消息,实现消费能力的水平扩展。 - 消费者(Consumer):
RocketMQ 消费消息的运行实体,一般集成在业务调用链路的下游。消费者必须指定到某一个消费者组中。 - 订阅关系(Subscription):
RocketMQ 发布订阅模型中消息过滤、重试、消费进度的规则配置。订阅关系以消费组粒度进行管理,消费组通过定义订阅关系控制指定消费组下的消费者如何实现消息过滤、消费重试及消费进度恢复等。RocketMQ 的订阅关系除过滤表达式之外都是持久化的,即服务端重启或请求断开,订阅关系依然保留。
Docker部署单机RocketMQ
1. 前言
部署RocketMQ的最核心是部署nameserver以及部署broker。然后,我们还需要安装可视化界面,在RocketMQ的官网上提供的是基础的安装方式。
2. 拉取镜像
git clone https://github.com/apache/rocketmq-docker.git
该命令会拉取最新的rocketmq镜像。
下载好之后,可以通过访问 Index of /dist/rocketmq 命令来查看rocketmq镜像的版本。
下载好之后 执行cd rocketmq-docker
命令跳转到 ./rockeetmq-docker
命令。
然后,跳转到 image-build
目录,然后,执行 build-image.sh 命令构建镜像。
cd image-build
sh build-image.sh 5.1.3 alpine
docker images
3. 下载可视化工具镜像
docker pull apacherocketmq/rocketmq-dashboard:latest
4. broker配置
这里自定义一个路径用于存放broker的配置,然后在此路径下创建一个broker.conf的文件。
mkdir -p /Users/manongfeige/config/rocketmq
cd /Users/manongfeige/config/rocketmq/
touch broker.conf
vim broker.conf
broker.conf文件的配置信息如下:
# 所属集群名称,如果节点较多可以配置多个
brokerClusterName = DefaultCluster
#broker名称,master和slave使用相同的名称,表明他们的主从关系
brokerName = broker-a
#0表示Master,大于0表示不同的slave
brokerId = 0
#表示几点做消息删除动作,默认是凌晨4点
deleteWhen = 04
#在磁盘上保留消息的时长,单位是小时
fileReservedTime = 48
#有三个值:SYNC_MASTER,ASYNC_MASTER,SLAVE;同步和异步表示Master和Slave之间同步数据的机制;
brokerRole = ASYNC_MASTER
#刷盘策略,取值为:ASYNC_FLUSH,SYNC_FLUSH表示同步刷盘和异步刷盘;SYNC_FLUSH消息写入磁盘后才返回成功
状态,ASYNC_FLUSH不需要;
flushDiskType = ASYNC_FLUSH
# 设置broker节点所在服务器的ip地址、物理ip,不能用127.0.0.1、localhost、docker内网ip
brokerIP1 = 192.168.41.121
这里需要注意的是设置broker节点所在的服务器ip地址,必须是真实的物理ip,不能用127.0.0.1、localhost、docker内网ip。
在mac电脑中通过 ifconfig
命令来查看。
配置好broker.conf,接着配置启动 RocketMQ的yml文件。这里创建一个 rocketmq.yml 文件,跟broker.conf文件放在同一个目录下。
5.启动文件 rocketmq.yml 配置
version: '3'
services:
namesrv:
image: apache/rocketmq:5.1.3-alpine
container_name: rmqnamesrv
ports:
- 9876:9876
command: sh mqnamesrv
broker:
image: apache/rocketmq:5.1.3-alpine
container_name: rmqbroker
ports:
- 10909:10909
- 10911:10911
- 10912:10912
volumes:
- /Users/manongfeige/config/rocketmq/broker.conf:/home/rocketmq/rocketmq-5.1.3/conf/broker.conf
command: sh mqbroker -n namesrv:9876 -c /home/rocketmq/rocketmq-5.1.3/conf/broker.conf
depends_on:
- namesrv
mqconsole:
image: apacherocketmq/rocketmq-dashboard
container_name: rmqdashboard
ports:
- 8181:8080
environment:
JAVA_OPTS: -Drocketmq.config.namesrvAddr=namesrv:9876 -Drocketmq.config.isVIPChannel=false
depends_on:
- namesrv
此配置文件主要分为三部分:
- 第一部分是:nameserver的配置。nameserver默认的端口是 9876。镜像的话这里指定为:apache/rocketmq:5.1.3-alpine。如果版本不同需要做对应的修改。如果不知道你的镜像是啥可以在docker中查看。
- 配置broker
broker 需要注意的是将前面配置的 broker.conf 文件映射到容器中的/home/rocketmq/rocketmq-5.1.3/conf/broker.conf
中去。 - 配置myconsole
主要是设置使用的镜像,容器的名称以及使用的端口号。console 依赖的是Java环境以及nameserver。
配置好之后,接着执行如下命令:
docker-compose -f rocketmq.yml up -d
启动正常的命令应该是这样的,然后。我们访问一下 http://localhost:8181/#/producer 控制台。
6. 测试消息的发送和接收
首先,在pom.xml文件中添加RocketMQ的依赖:
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.2.3</version>
</dependency>
在application.properties文件中配置RocketMQ的相关信息:
rocketmq.name-server=192.168.31.191:9876
rocketmq.producer.group=myProducerGroup
创建一个生产者类:
@Component
public class Producer {
@Autowired
private RocketMQTemplate rocketMQTemplate;
public void sendMessage(String topic, String message) {
rocketMQTemplate.convertAndSend(topic, message);
}
}
创建一个消费者类:
@Service
@RocketMQMessageListener(topic = "test_topic", consumerGroup = "test_consumer_group")
public class Consumer implements RocketMQListener<String> {
@Override
public void onMessage(String s) {
System.out.println("Received message:" + s);
}
}
在主类中调用生产者发送消息:
@SpringBootApplication
public class RocketmqDemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(RocketmqDemoApplication.class, args);
Producer producer = run.getBean(Producer.class);
producer.sendMessage("test_topic", "你好呀,码农飞哥");
}
}
RocketMQ集群搭建
一、集群特点
- NameServer是一个几乎无状态的节点,可集群部署,节点之间不会互相通信。
- Broker部署相对比较复杂,Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master。Master与Slave可以通过指定相同的BrokerName,不同的BrokerId来区分,BrokerId为0表示Master,BrokerId大于0表示Slave。
- Producer与NameServer集群中的其中一个节点(随机选择)建立长链接,定期从NameServer取Topic路由信息,并向Topic服务的Master建立长链接(也就是说根据Topic的路由信息找到向哪个Broker发送消息),且定时向Master发送心跳,Producer完全无状态,可集群部署。
- Consumer与NameServer集群中的其中一个节点(随机选择)建立长链接,定期从NameServer取Topic路由信息,并向Topic服务的Master,Slave建立长链接,且定时向Master,Slave发送心跳,Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅关系由Broker配置决定。
二、服务器环境
1.1.部署架构
使用的模式是 2m-2s-sync,双主双从,同步复制
1.2.服务器信息
IP | 角色 | 架构模式 |
192.31.186.198 | nameserver,broker | master1,slave2 |
192.31.184.89 | nameserver,broker | master2,slave1 |
1.3.配置Host (两台服务器都需要)
- nameserver机器信息
#nameserver
172.31.186.180 rocketmq-nameserver1
172.31.184.89 rocketmq-nameserver2
#broker 机器信息
172.31.186.180 rocketmq-master1
172.31.186.180 rocketmq-slave2
172.31.184.89 rocketmq-master2
172.31.184.89 rocketmq-slave1
配置完成之后,重启网卡。
systemctl restart network
1.4. 安装jdk(两台服务器都需要)
安装jdk-8u192-linux-x64.rpm,此处省略。
1.5. 关闭防火墙(两台服务器都需要)
首先查看防火墙的状态,如果状态是 active 则表示防火墙开启
$ systemctl status firewalld
关闭防火墙
$ systemctl stop firewalld
1.6. 创建数据存储目录(两台服务器都需要)
创建master节点的存储路径
mkdir -p /data/server/feige/rocketmq/store
mkdir -p /data/server/feige/rocketmq/store/commitlog
mkdir -p /data/server/feige/rocketmq/store/consumequeue
mkdir -p /data/server/feige/rocketmq/store/index
创建slave节点的存储路径
mkdir -p /data/server/feige/rocketmq/store-s
mkdir -p /data/server/feige/rocketmq/store-s/commitlog
mkdir -p /data/server/feige/rocketmq/store-s/consumequeue
mkdir -p /data/server/feige/rocketmq/store-s/index
三、下载与安装配置
2.1.下载rocketmq并解压(两天服务器都要)
cd /data/server/feige
wget https://archive.apache.org/dist/rocketmq/5.1.3/rocketmq-all-5.1.3-bin-release.zip
unzip rocketmq-all-5.1.3-bin-release.zip -d /data/server/feige/rocketmq
cd /data/server/feige/rocketmq/rocketmq-all-5.1.3-bin-release
2.2. 环境变量配置(两台服务器都需要)
vim /etc/profile
在profile文件的末尾加入如下命令:
ROCKETMQ_HOME=/data/server/feige/rocketmq/rocketmq-all-5.1.3-bin-release
PATH=$PATH:$ROCKETMQ_HOME/bin
export ROCKETMQ_HOME PATH
执行 source /etc/profile
使文件生效
2.3. 配置 rocketmq broker-a (在Master1上操作)
vim conf/2m-2s-sync/broker-a.properties
在此配置文件中添加,master默认的端口是10911。
#所属集群名称
brokerClusterName=rocketmq-cluster
#broker名字,注意此处不同的配置文件填写的不一样;主从节点一样,也就是这个值区分broker组的;
brokerName=broker-a
#主从标识:0 表示Master, >0 表示Slave;同一个组中区分主从的标识,只能有一个主;
brokerId=0
#当前broker监听的IP
brokerIP1=172.31.186.180
#用于HA主从同步
brokerIP2=172.31.186.180
#nameServer地址,分号分割
namesrvAddr=rocketmq-nameserver1:9876;rocketmq-nameserver2:9876
#在发消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许Broker自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许Broker自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#Broker 对外服务的监听端口
listenPort=10911
haListenPort=10912
#删除长期无用文件时间点,默认凌晨4点
deleteWhen=04
#文件保留时间(h),默认48小时
fileReservedTime=48
#commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#检测物理文件磁盘空间使用率
diskMaxUsedSpaceRatio=88
#存储路径
storePathRootDir=/data/server/feige/rocketmq/store
#commitLog存储路径
storePathCommitLog=/data/server/feige/rocketmq/store/commitlog
#消费队列存储路径
storePathConsumeQueue=/data/server/feige/rocketmq/store/consumequeue
#消息索引存储路径
storePathIndex=/data/server/feige/rocketmq/store/index
#checkpoint 文件存储路径
storeCheckPoint=/data/server/feige/rocketmq/store/checkpoint
#abort 文件存储路径
abortFile=/data/server/feige/rocketmq/store/abort
#限制的消息大小
maxMessageSize=65536
#broker角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE 从节点
brokerRole=SYNC_MASTER
#刷盘策略
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
2.4. 配置 rocketmq broker-b-s (在Slave2上配置)
这里为了避免与master的端口冲突,将slave的默认端口改成11011,另外还需要将从节点broker的存储路径改下,不能与master节点共用。
#所属集群名称
brokerClusterName=rocketmq-cluster
#broker名字,注意此处不同的配置文件填写的不一样
brokerName=broker-b
#主从标识:0 表示Master, >0 表示Slave
brokerId=1
#当前broker监听的IP
brokerIP1=172.31.186.180
#用于HA主从同步
brokerIP2=172.31.186.180
#nameServer地址,分号分割
namesrvAddr=rocketmq-nameserver1:9876;rocketmq-nameserver2:9876
#在发消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许Broker自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许Broker自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#Broker 对外服务的监听端口
listenPort=11011
haListenPort=11012
#删除长期无用文件时间点,默认凌晨4点
deleteWhen=04
#文件保留时间(h),默认48小时
fileReservedTime=48
#commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
#存储路径
storePathRootDir=/data/server/feige/rocketmq/store-s
#commitLog存储路径
storePathCommitLog=/data/server/feige/rocketmq/store-s/commitlog
#消费队列存储路径
storePathConsumeQueue=/data/server/feige/rocketmq/store-s/consumequeue
#消息索引存储路径
storePathIndex=/data/server/feige/rocketmq/store-s/index
#checkpoint 文件存储路径
storeCheckPoint=/data/server/feige/rocketmq/store-s/checkpoint
#abort 文件存储路径
abortFile=/data/server/feige/rocketmq/store-s/abort
#限制的消息大小
maxMessageSize=65536
#broker角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE 从节点
brokerRole=SLAVE
#刷盘策略
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
2.5. 配置 rocketmq broker-b.properties(在Master2上操作)
执行
vim conf/2m-2s-sync/broker-b.properties
在此配置文件中添加:master默认的端口是10911。
#所属集群名称
brokerClusterName=rocketmq-cluster
#broker名字,注意此处不同的配置文件填写的不一样
brokerName=broker-b
#主从标识:0 表示Master, >0 表示Slave
brokerId=0
#当前broker监听的IP
brokerIP1=172.31.184.89
#用于HA主从同步
brokerIP2=172.31.184.89
#nameServer地址,分号分割
namesrvAddr=rocketmq-nameserver1:9876;rocketmq-nameserver2:9876
#在发消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许Broker自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许Broker自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#Broker 对外服务的监听端口
listenPort=10911
haListenPort=10912
#删除长期无用文件时间点,默认凌晨4点
deleteWhen=04
#文件保留时间(h),默认48小时
fileReservedTime=48
#commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
#存储路径
storePathRootDir=/data/server/feige/rocketmq/store
#commitLog存储路径
storePathCommitLog=/data/server/feige/rocketmq/store/commitlog
#消费队列存储路径
storePathConsumeQueue=/data/server/feige/rocketmq/store/consumequeue
#消息索引存储路径
storePathIndex=/data/server/feige/rocketmq/store/index
#checkpoint 文件存储路径
storeCheckPoint=/data/server/feige/rocketmq/store/checkpoint
#abort 文件存储路径
abortFile=/data/server/feige/rocketmq/store/abort
#限制的消息大小
maxMessageSize=65536
#broker角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE 从节点
brokerRole=SYNC_MASTER
#刷盘策略
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
2.6. 配置rocketmq broker-a-s.properties(在Slave1上操作)
vim conf/2m-2s-sync/broker-a-s.properties
在此配置文件中添加:将slave的默认端口改成11011。这里从节点的存储路径要与主节点区分,主和从都必须有
#所属集群名称
brokerClusterName=rocketmq-cluster
#broker名字,注意此处不同的配置文件填写的不一样
brokerName=broker-a
#主从标识:0 表示Master, >0 表示Slave
brokerId=1
#当前broker监听的IP
brokerIP1=172.31.184.89
#用于HA主从同步
brokerIP2=172.31.184.89
#nameServer地址,分号分割
namesrvAddr=rocketmq-nameserver1:9876;rocketmq-nameserver2:9876
#在发消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许Broker自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许Broker自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#Broker 对外服务的监听端口
listenPort=11011
haListenPort=11012
#删除长期无用文件时间点,默认凌晨4点
deleteWhen=04
#文件保留时间(h),默认48小时
fileReservedTime=48
#commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
#存储路径
storePathRootDir=/data/server/feige/rocketmq/store-s
#commitLog存储路径
storePathCommitLog=/data/server/feige/rocketmq/store-s/commitlog
#消费队列存储路径
storePathConsumeQueue=/data/server/feige/rocketmq/store-s/consumequeue
#消息索引存储路径
storePathIndex=/data/server/feige/rocketmq/store-s/index
#checkpoint 文件存储路径
storeCheckPoint=/data/server/feige/rocketmq/store-s/checkpoint
#abort 文件存储路径
abortFile=/data/server/feige/rocketmq/store-s/abort
#限制的消息大小
maxMessageSize=65536
#broker角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE 从节点
brokerRole=SLAVE
#刷盘策略
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
2.7. 测试环境JVM配置(两台机器都要执行)
RocketMQ默认占用的内存是8G,比较大,这里需要修改下占用的堆内存,不然在一个机器是上同时启动两个 broker可能会启动失败。
vim bin/runbroker.sh
# 根据机器实际内存调整,这里演示的机器内存比较小,配置的值比较小
JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn128m"
vim bin/runserver.sh
# 根据机器实际内存调整,这里演示的机器内存比较小,配置的值比较小
JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
vim bin/tools.sh
# 根据机器实际内存调整,这里演示的机器内存比较小,配置的值比较小
JAVA_OPT="${JAVA_OPT} -server -Xms128m -Xmx128m -Xmn256m -XX:PermSize=128m -XX:MaxPermSize=128m"
2.8. 生产环境JVM配置
vim bin/runbroker.sh
JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g"
vim bin/runserver.sh
JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
vim bin/tools.sh
JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn256m -XX:PermSize=128m -XX:MaxPermSize=128m"
四、启动集群
3.1.启动nameserver((两台机器上都执行)
nohup sh bin/mqnamesrv > /data/server/feige/rocketmq/logs/mqnamesrv.log 2>&1 &
3.2.启动broker
在192.31.186.180上执行如下命令
#1.启动Master1,在Master1上操作
nohup sh bin/mqbroker -c conf/2m-2s-sync/broker-a.properties > /data/server/feige/rocketmq/logs/broker-a.log 2>&1 &
#2.启动Slave2,在Slave 2上操作
nohup sh bin/mqbroker -c conf/2m-2s-sync/broker-b-s.properties > /data/server/feige/rocketmq/logs/broker-b-s.log 2>&1 &
#6、查看 NameServer(9876)和 Broker(10909、10911、10912)启动情况,在2台主机上操作
netstat -nltup|egrep "9876|10911|10912|11011|11012"
在192.31.184.89上执行如下命令:
#1.启动Master2,在Master2上操作
nohup sh bin/mqbroker -c conf/2m-2s-sync/broker-b.properties > /data/server/feige/rocketmq/logs/broker-b.log 2>&1 &
#2.启动Slave1,在Slave1上操作
nohup sh bin/mqbroker -c conf/2m-2s-sync/broker-a-s.properties > /data/server/feige/rocketmq/logs/broker-a-s.log 2>&1 &
#6、查看 NameServer(9876)和 Broker(10909、10911、10912)启动情况,在2台主机上操作
netstat -nltup|egrep "9876|10911|10912|11011|11012"
或者
sh bin/mqadmin clusterList -n "172.31.184.89:9876;172.31.186.180:9876"
或者
jps
3.3.测试集群生产消费情况
#在2台主机上操作
vim /etc/profile
#在文件/etc/profile中追加
export NAMESRV_ADDR="rocketmq-nameserver1:9876;rocketmq-nameserver2:9876"
#在控制台在其中1台机器上操作,启动一个生产者,在1个消费者机器就可以看到消费信息
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
#在控制台其中2台机器上操作,启动2个消费者
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
这里的NAMESRV_ADDR变量名不能做任何修改,不然就可能报连不上Nameserver的错误。
正常消费成功的话,则消费者出现如下日志:
3.5. 关闭命令
#关闭broker命令:
sh bin/mqshutdown broker
#关闭namesrv命令:
sh bin/mqshutdown namesrv
五、问题总结
java.lang.RuntimeException: Lock failed,MQ already started
at org.apache.rocketmq.store.DefaultMessageStore.start(DefaultMessageStore.java:214)
at org.apache.rocketmq.broker.BrokerController.start(BrokerController.java:827)
at org.apache.rocketmq.broker.BrokerStartup.start(BrokerStartup.java:64)
at org.apache.rocketmq.broker.BrokerStartup.main(BrokerStartup.java:58)
- 检查master节点和slave节点的端口是否冲突
- 检查master节点和slave节点的broker的存储路径是否冲突
六、安装管理面板
官网提供了两种部署方式,docker部署和源码部署,由于前面我们都是使用的直接部署,所以这里也采用官网提供的源码部署的方式。 (PS:docker 部署也尝试了,一直不行)。
- 下载源代码,源码地址:https://github.com/apache/rocketmq-dashboard/tags
- 在本地解压源码,然后,对源码进行编译打包,打包命令是:
$ mvn clean package -Dmaven.test.skip=true
然后,将生成的 rocketmq-dashboard-1.0.0.jar包上传到服务器,jar的相对路径是 target\rocketmq-dashboard-1.0.0.jar
- 运行
rocketmq-dashboard-1.0.0.jar
nohup java -jar rocketmq-dashboard-1.0.0.jar --server.port=18080 --rocketmq.config.namesrvAddr='172.31.184.89:9876;172.31.186.180:9876'>/data/server/feige/rocketmq/logs/mq-console.log 2>&1 &
这里需要指定两个参数:
-
--server.port=18080
设置端口是18080,因为默认的端口是8080,很可能会冲突 -
--rocketmq.config.namesrvAddr='192.31.184.89:9876;192.31.186.180:9876'
用于指定nameserver集群的地址,不指定的话会有问题。
启动成功之后访问控制台:http://192.31.186.180:18080/