文章目录
前言
本文的内容在于了解 RocketMQ 的集群模式,单机部署 RocketMQ,本地和服务器上运行 RocketMQ 的监控平台,将 RocketMQ 引入到自己的项目之中。
一、RocketMQ 的安装
关于 RocketMQ 的安装,之前有写过这方面的博客,如果你的服务器上面还没有安装上 RocketMQ 的话,可借鉴博客:RocketMQ 在Linux上的安装
二、RocketMQ 集群
关于 RocletMQ 的搭建,有必要提前了解它的角色以及集群模式。
1. 各种角色介绍
RocketMQ网络部署图如下:
集群搭建首先得明白 RocketMQ 的各种角色:
- Producer:消息的发送者
- Consumer:消息接收者
- Broker:暂存和传输消息
- NameServer:管理Broker
- Topic:区分消息的种类;一个发送者可以发送消息给一个或者多个Topic;一个消息的接收者可以订阅一个或者多个Topic消息
- Message Queue:相当于是Topic的分区;用于并行发送和接收消息
(1)NameServer 集群
- NameServer 是一个无状态的节点,可集群部署,节点都是各自独立的,无任何信息同步。
(2)Broker 集群
- Broker 分为 Master 与 Slave,一个 Master 可以对应多个 Slave,但一个 Slave 只能对应一个Master;
- Master 与 Slave 的对应关系通过指定相同的 BrokerName,不同的 BrokerID 来定义,id 为 0 表示 Master, 非 0 表示 Slave;
- 可以部署多个 Master 实现 Broker 集群,即多组 Master - Slave 的 Broker 节点;
- Master 通常用于写入数据,Slave 用于读取数据;
- 每个 Broker 与 NameServer 集群中的所有节点建立长连接,定时注册 Topic 信息到所有 NameServer;
(3)Producer 集群
- Producer 为消息的生产者,都是各自独立的无状态的节点,可以认为只要向 mq 中推送消息的节点都算作 Producer 节点。
- Producer 节点与 NameServer 集群中的随机一个节点建立长连接,定期从 NameServer 取出 Topic 路由信息,并向提供 Topic 服务的 Master 建立长连接,且定时向 Master 发送心跳。
(4)Customer 集群
- Customer 为消息的消费者,都是各自独立的无状态的节点,可以认为只要向 mq 中获取消息的节点都算作 Customer 节点;
- Customer 节点与 NameServer 集群中的随机一个节点建立长连接,定期从 NameServer 取出 Topic 路由信息,并向提供 Topic 服务的 Master、Slave 建立长连接,且定时向 Master、Slave 发送心跳;
- Customer 节点既可以从 Master 订阅消息,也可以从 Slave 订阅消息,订阅规则由 Broker 配置决定;
2. 集群模式
(1)单Master模式
- 这种方式风险较大,一旦Broker重启或者宕机时,会导致整个服务不可用。不建议线上环境使用,可以用于本地测试。
(1)多Master模式
- 一个集群无Slave,全是Master,例如2个Master或者3个Master,这种模式的优缺点如下:
- 优点:配置简单,单个Master宕机或重启维护对应用无影响,在磁盘配置为RAID10时,即使机器宕机不可恢复情况下,由于RAID10磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢),性能最高;
- 缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到影响。
(1)多Master多Slave模式(异步)
- 每个Master配置一个Slave,有多对Master-Slave,HA采用异步复制方式,主备有短暂消息延迟(毫秒级),这种模式的优缺点如下:
- 优点:即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,同时Master宕机后,消费者仍然可以从Slave消费,而且此过程对应用透明,不需要人工干预,性能同多Master模式几乎一样;
- 缺点:Master宕机,磁盘损坏情况下会丢失少量消息。
(1)多Master多Slave模式(同步)
- 每个Master配置一个Slave,有多对Master-Slave,HA采用同步双写方式,即只有主备都写成功,才向应用返回成功,这种模式的优缺点如下:
- 优点:数据与服务都无单点故障,Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高;
- 缺点:性能比异步复制模式略低(大约低10%左右),发送单个消息的RT会略高,且目前版本在主节点宕机后,备机不能自动切换为主机。
以上集群内容来自 每天都要进步一点点 的博客:RocketMQ(五)RocketMQ集群架构
三、RocketMQ 单机搭建
网上很多都是博客啊,教程啊都会教你如何搭建 RocketMQ 的集群,但是作为初学者,或者是不想在自己电脑上开启多个虚拟机,又或者是只有一个服务器只是简简单单学习一下并且运用到项目之中,等等原因没必要搭建集群的话,单机搭建也是 OK 的,如果是线上项目用的话可以绕着走了。
1. 创建存储目录
这一步非必须,因为就算没有指定日志存储目录,RockeMQ 会默认将日志文件放在 /root
目录下的 logs/rocketmqlogs
下,或者可以指定存放日志文件。
先大概说一下,我目前 RocketMQ 是安装在 /soft/rocketmq
目录下的,同级还有一个 store
文件夹,文件夹下面有还有四个文件夹,分别是:commitlog
、config
、consumequeue
、index
存储 RocketMQ 的一些日志文件等。结构如下图所示:
如果你跟着上面提供的链接安装 RocketMQ 的话,应该是有 /soft/rocketmq/rocketmq-all-4.4.0-bin-release
这个目录的,想跟着我走只需要再创建 /soft/rocketmq/store
目录以及该目录以下的目录就行,linux 命令如下:
mkdir /sfot/rocketmq/store
mkdir /sfot/rocketmq/store/commitlog
mkdir /sfot/rocketmq/store/config
mkdir /sfot/rocketmq/store/consumequeue
mkdir /sfot/rocketmq/store/index
2. 环境变量配置
RocketMQ 的环境变量配置,其实不是很重要,这里还是加上去,跟 JAVA 的环境配置差不都
编辑 profile
文件,命令:vim /etc/profile
在该文件末尾加上以下配置:
#set rocketmq
ROCKETMQ_HOME=/soft/rocketmq/rocketmq-all-4.4.0-bin-release
PATH=$PATH:$ROCKETMQ_HOME/bin
export ROCKETMQ_HOME PATH
这里只要注意 ROCKETMQ_HOME
的配置是你 RocketMQ 的安装目录就行,别打错
3. 防火墙配置
如果你的 RocketMQ 是运行在自己虚拟机上面的
宿主机需要远程访问虚拟机的 rocketmq 服务和web服务,需要开放相关的端口号,简单粗暴的方式是直接关闭防火墙
# 关闭防火墙
systemctl stop firewalld.service
# 查看防火墙的状态
firewall-cmd --state
# 禁止firewall开机启动
systemctl disable firewalld.service
或者为了安全,只开放特定的端口号,RocketMQ默认使用3个端口:9876 、10911 、11011 。如果防火墙没有关闭的话,那么防火墙就必须开放这些端口:
- nameserver 默认使用 9876 端口
- master 默认使用 10911 端口
- slave 默认使用11011 端口
执行以下命令:
# 关闭防火墙
# 开放name server默认端口
firewall-cmd --remove-port=9876/tcp --permanent
# 开放master默认端口
firewall-cmd --remove-port=10911/tcp --permanent
# 开放slave默认端口 (当前集群模式可不开启)
firewall-cmd --remove-port=11011/tcp --permanent
# 重启防火墙
firewall-cmd --reload
但是,如果你 RocketMQ 并不是安装在虚拟机上的,而是放到云服务器上面,那你必须还得在云服务上面开放这几个端口
比方说我的 RocketMQ 是运行在 某某云
上面的,我就得做如下设置:
找到我的服务器,点击 更多
,选择 管理
进入下一个页面之后,选择 防火墙
在防火墙中开放 11011
、10911
、9876
这几个端口
以上操作不同云服务器可能不同,但是都差不多,个人建议有条件的话可以自己买一个云服务器用于学习,毕竟开虚拟机首先比较麻烦,其次是虚拟机还是挺占用电脑资源的。
4 . broker 配置文件
这里我是直接使用 RocketMQ /conf
目录下的 broker.conf
文件作为配置文件了,我的配置如下:
# 这里是之前的配置,我把它注释掉了
# brokerClusterName = DefaultCluster
# brokerName = broker-a
# brokerId = 0
# deleteWhen = 04
# fileReservedTime = 48
# brokerRole = ASYNC_MASTER
# flushDiskType = ASYNC_FLUSH
#所属集群名字
brokerClusterName=DefaultCluster
#broker名字
brokerName=broker-a
#0 表示 Master,>0 表示 Slave
brokerId=0
#删除文件时间点,默认凌晨 4点
deleteWhen=04
#文件保留时间,默认 48 小时
fileReservedTime=48
#Broker 的角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE
brokerRole=ASYNC_MASTER
#刷盘方式
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#Broker 对外服务的监听端口
listenPort=10911
#存储路径
storePathRootDir=/soft/rocketmq/store
#commitLog 存储路径
storePathCommitLog=/soft/rocketmq/store/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/soft/rocketmq/store/comsumequeue
#消息索引存储路径
storePathIndex=/soft/rocketmq/store/index
#checkpoint 文件存储路径
storeCheckpoint=/soft/rocketmq/store/checkpoint
#abort 文件存储路径
abortFile=/soft/rocketmq/store/abort
#nameServer地址,分号分割
namesrvAddr=XXX.XXX.XXX.XX:9876
#brokerIP1
brokerIP1=XXX.XXX.XXX.XX
你可以讲以上配置直接替换掉 broker.conf
这个文件原本的内容,这里需要注意的是 namesrvAddr
和 brokerIP1
这两个配置,如果你 RocketMQ 是在虚拟机上面运行的话,这里配的就是你服务的 IP 地址,用 ifconfig
命令就可以查看。但如果你的 RocketMQ 是在云服务器上面运行的话,这里的地址要使用服务器 (公网)地址
。
5. 启动 RocketMQ
(1)停止正在运行的 RocketMQ
如果你服务器上面已经启动过了 RocketMQ 的话,需要把它给关掉
进入 RocketMQ 的 /bin
目录下
关闭 NameServer:sh mqshutdown namesrv
关闭 Broker:sh mqshutdown broker
(2)启动 NameServer
命令:nohup sh mqnamesrv &
(2)启动 Broker
这里如果你服务器比较小,需要修改 runserver.sh
和 runbroker.sh
的内存配置,这里不赘述了,依旧可参考上面 RocketMQ 的安装教程,我就直接启动了
命令:nohup sh mqbroker -c /soft/rocketmq/rocketmq-all-4.4.0-bin-release/conf/broker.conf &
以上命令就是让 broker 以指定配置文件启动,就是之前的那个 broker 配置文件
(2)检查 RocketMQ 的启动
可用命令:jps
来查看 RocketMQ 是否启动
如果能看到 NamesrvStartup
和 BrokerStartup
的话就表明单机版的 RocketMQ 启动成功了
四、监控平台的搭建
RocketMQ 有一个专门的监控平台来查看 MQ 的情况,大概长这样子
1. 下载 console 源码
下载链接:https://github.com/apache/rocketmq-externals
可以通过 git
把它给拉下来,可以看到这里面有 rocketmq 与各种各样的技术集成,但是这个监控平台只需要启动 rocketmq-console
这个服务就行了
以下是我下载的:
链接:百度网盘链接
提取码:no5x
找个目录存放,然后解压下来。
2. 防火墙设置
你的 RocketMQ 要是运行在虚拟机上面的话可跳过这一步,
因为我的 RocketMQ 是运行在云服务器上面的,所以还需要对外开放两个端口:8080
、10909
,一个是 监控平台的端口号 8080
(如果你想把这个监控平台也运行到你服务器上面去的话就需要开放),另一个 10909
是 RocketMQ vip通道端口,也把它开启算了,不开影响也不大,就是运行的时候可能会报错,我就都打开了
3. IDEA 启动
进入 IDEA ,打开 rocketmq-console
项目
IDEA 打开以后,修改配置文件 application.properties
主要是将 rocketmq.config.namesrvAddr
设置成你 RocketMQ 所运行的服务器 IP (公网
)地址,然后就可以直接启动了
启动完成之后游览器上输入:localhost:8080
,访问
到目前位置,就用 IDEA 启动成功了,里面的每个按钮、什么功能可以自己去摸索。
3. 部署到 linux 服务器上
如果你想把这个 RocketMQ 的监控平台运行到服务器上面,可以直接使用 IDEA 进行打包
打包完成之后会生成 target
文件夹,文件夹下的 rocketmq-console-ng-1.0.1.jar
文件就是需要上传到服务器上运行的 jar 包了
可通过以上方式快速定位到改文件所在位置
在 Linux 创建个文件夹存放该 jar 包
命令:mkdir /a-mike/rocketmq-console
进入该目录下,rz
命令上传文件
后台运行 jar 包
命令:nohup java -jar rocketmq-console-ng-1.0.1.jar &
启动完成之后,就可以在游览器上面输入 服务器IP(公网):8080
,打开监控平台了。
五、项目引入
以我自己的项目为例,spring cloud 整合 RocketMQ,项目结构如下
pom.xml
文件添加配置
<!--RocketMQ-->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.8.0</version>
</dependency>
application.properties
添加配置
spring:
application:
name: mike-service-message
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: f90ad91c-ac39-4a2d-8fb3-fcd33ded9534
stream:
rocketmq:
binder:
name-server: XXX.XXX.XXX.XX:9876
bindings:
input:
destination: stream-mike-topic
# rocketmq一定要设置group(随便写) 其他的mq可留空
group: mike-group
# rocketMQ配置
rocketmq:
# name server地址
name-server: XXX.XXX.XXX.XX:9876
producer:
group: mike-group
Message.java
类
public class Message {
private String title;// 消息头
private String content;// 消息内容
public Message() {
}
public Message(String title, String content) {
this.title = title;
this.content = content;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "Message{" +
"title='" + title + '\'' +
", content='" + content + '\'' +
'}';
}
}
MessageListener.java
类
@Slf4j
@Service
// consumerGroup、topic要与消息生产者一致
@RocketMQMessageListener(consumerGroup = "mike_message", topic = "mike_message")
public class MessageListener implements RocketMQListener<Message> {
@Override
public void onMessage(Message message) {
System.err.println("我收到啦~~");
System.err.println("message = " + message);
}
}
这个 MessageListener.java
消息监听器,就是从 RocketMQ 中拿消息,然后进行消费。
写一个简单的接口,功能就是往 RocketMQ 中塞一个主题为 mike-message
的消息,然后等它被 MessageListener 消费掉
MessageController.java
类中
@PostMapping(value = "/send-test-msg")
public String test() {
messageService.test();
return "message send success";
}
MessageService.java
类中
void test();
MessageServiceImpl.java
类中
@Override
public void test() {
Message message = new Message();
message.setTitle("米大大");
message.setContent("不愧是你");
rocketMQTemplate.convertAndSend("mike_message",message);
}
运行该项目,使用 postman 测试
控制台打印:
可以看到请求接口之后,往 RocketMQ 中发送消息,该消息又被消费到。
以上内容虽然不能保证作为初学者很好的掌握 RocketMQ 这个技术,但是能快速上手,并且运用到项目之中,希望对大家有所帮助。