学任何技术都是两步骤:
-
搭建环境
-
helloworld
我也不例外,直接搞起来。
一、RocketMQ的安装
1、文档
官方网站
http://rocketmq.apache.org
GitHub
https://github.com/apache/rocketmq
2、下载
wget https://mirror.bit.edu.cn/apache/rocketmq/4.7.0/rocketmq-all-4.7.0-bin-release.zip
我们是基于Centos8来的,面向官方文档学习,所以下载地址自然也是官方的。
去官方网站找合适的版本进行下载,目前我这里最新的是4.7.0版本。
http://rocketmq.apache.org/dowloading/releases/
https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.7.0/rocketmq-all-4.7.0-bin-release.zip
3、准备工作
3.1、解压
unzip rocketmq-all-4.7.0-bin-release.zip
3.2、安装jdk
sudo yum install java-1.8.0-openjdk-devel
4、启动
4.1、启动namesrv
cd rocketmq-all-4.7.0-bin-release/bin
./mqnamesrv
4.2、启动broker
cd rocketmq-all-4.7.0-bin-release/bin
./mqbroker -n localhost:9876
常见错误以及解决方案:
常见错误:启动broker失败 Cannot allocate memory
[root@node-113b bin]# ./mqbroker -n localhost:9876
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000005c0000000, 8589934592, 0) failed
; error='Cannot allocate memory' (errno=12)#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 8589934592 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /usr/local/rocketmq/bin/hs_err_pid1997.log
解决方案:
是由于默认内存分配的太大了,超出了本机内存,直接OOM了。
修改bin/目录下的如下两个脚本
runbroker.sh
runserver.sh
在这两个脚本里都搜索-server -Xms
,将其内存分配小点,自己玩的话512MB就足够了,够够的了!
4.3、启动成功标识
namesrv启动成功标识:
broker启动成功标识:
二、RocketMQ控制台的安装
控制台目前获取方式有如下两种:
-
第三方网站去下载现成的,比如csdn等。
-
官方源码包自己编译而成,官方没有现成的。
我们这里当然采取官方方式。
1、官方文档
github仓库
https://github.com/apache/rocketmq-externals
中文指南
https://github.com/apache/rocketmq-externals/blob/master/rocketmq-console/doc/1_0_0/UserGuide_CN.md
2、下载源码
https://codeload.github.com/apache/rocketmq-externals/zip/master
3、修改配置(可选)
我们下载完解压后的文件目录如下:
修改rocketmq-console\src\main\resources\application.properties
文件的server.port
就欧了。默认8080。
4、编译打包
进入rocketmq-console
,然后用maven进行编译打包
mvn clean package -DskipTests
打包完会在target下生成我们spring boot的jar程序,直接java -jar
启动完事。
5、启动控制台
将编译打包好的springboot程序扔到服务器上,执行如下命令进行启动
java -jar rocketmq-console-ng-1.0.1.jar --rocketmq.config.namesrvAddr=127.0.0.1:9876
如果想后台启动就nohup &
访问一下看看效果:
三、测试
rocketmq给我们提供了测试工具和测试类,可以在安装完很方便的进行测试。
0、准备工作
rocketmq给我们提供的默认测试工具在bin目录下,叫tools.sh
。我们测试前需要配置这个脚本,为他指定namesrv地址才可以,否则测试发送/消费消息的时候会出现如下错误 connect to null failed:
22:49:02.470 [main] DEBUG i.n.u.i.l.InternalLoggerFactory - Using SLF4J as the default logging framework
RocketMQLog:WARN No appenders could be found for logger (io.netty.util.internal.PlatformDependent0).
RocketMQLog:WARN Please initialize the logger system properly.
java.lang.IllegalStateException: org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to null failed
配置如下:
vim tools.sh
# 在export JAVA_HOME上面添加如下这段代码
export NAMESRV_ADDR=localhost:9876
1、发送消息
./tools.sh org.apache.rocketmq.example.quickstart.Producer
成功的话会看到哗哗哗的日志,因为这个类会发送1000条消息到TopicTest这个Topic下。
2、消费消息
./tools.sh org.apache.rocketmq.example.quickstart.Consumer
成功的话会看到哗哗哗的日志,因为这个类会消费TopicTest下的全部消息。刚发送的1000条都会被消费掉。
3、控制台
发送成功后我们自然也能来到管控台去看消息和消费情况等等等信息
四、架构图以及角色
1、架构图
2、角色
2.1、Broker
-
理解成RocketMQ本身
-
broker主要用于producer和consumer接收和发送消息
-
broker会定时向nameserver提交自己的信息
-
是消息中间件的消息存储、转发服务器
-
每个Broker节点,在启动时,都会遍历NameServer列表,与每个NameServer建立长连接,注册自己的信息,之后定时上报
2.2、Nameserver
-
理解成zookeeper的效果,只是他没用zk,而是自己写了个nameserver来替代zk
-
底层由netty实现,提供了路由管理、服务注册、服务发现的功能,是一个无状态节点
-
nameserver是服务发现者,集群中各个角色(producer、broker、consumer等)都需要定时向nameserver上报自己的状态,以便互相发现彼此,超时不上报的话,nameserver会把它从列表中剔除
-
nameserver可以部署多个,当多个nameserver存在的时候,其他角色同时向他们上报信息,以保证高可用,
-
NameServer集群间互不通信,没有主备的概念
-
nameserver内存式存储,nameserver中的broker、topic等信息默认不会持久化,所以他是无状态节点
2.3、Producer
-
消息的生产者
-
随机选择其中一个NameServer节点建立长连接,获得Topic路由信息(包括topic下的queue,这些queue分布在哪些broker上等等)
-
接下来向提供topic服务的master建立长连接(因为rocketmq只有master才能写消息),且定时向master发送心跳
2.4、Consumer
-
消息的消费者
-
通过NameServer集群获得Topic的路由信息,连接到对应的Broker上消费消息
-
由于Master和Slave都可以读取消息,因此Consumer会与Master和Slave都建立连接进行消费消息
3、核心流程
-
Broker都注册到Nameserver上
-
Producer发消息的时候会从Nameserver上获取发消息的topic信息
-
Producer向提供服务的所有master建立长连接,且定时向master发送心跳
-
Consumer通过NameServer集群获得Topic的路由信息
-
Consumer会与所有的Master和所有的Slave都建立连接进行监听新消息
五、核心概念
1、Message
消息载体。Message发送或者消费的时候必须指定Topic。Message有一个可选的Tag项用于过滤消息,还可以添加额外的键值对。
2、topic
消息的逻辑分类,发消息之前必须要指定一个topic才能发,就是将这条消息发送到这个topic上。消费消息的时候指定这个topic进行消费。就是逻辑分类。
3、queue
1个Topic会被分为N个Queue,数量是可配置的。message本身其实是存储到queue上的,消费者消费的也是queue上的消息。多说一嘴,比如1个topic4个queue,有5个Consumer都在消费这个topic,那么会有一个consumer浪费掉了,因为负载均衡策略,每个consumer消费1个queue,5>4,溢出1个,这个会不工作。
4、Tag
Tag 是 Topic 的进一步细分,顾名思义,标签。每个发送的时候消息都能打tag,消费的时候可以根据tag进行过滤,选择性消费。
5、Message Model
消息模型:集群(Clustering)和广播(Broadcasting)
6、Message Order
消息顺序:顺序(Orderly)和并发(Concurrently)
7、Producer Group
消息生产者组
8、Consumer Group
消息消费者组
六、ACK
首先要明确一点:ACK机制是发生在Consumer端的,不是在Producer端的。也就是说Consumer消费完消息后要进行ACK确认,如果未确认则代表是消费失败,这时候Broker会进行重试策略(仅集群模式会重试)。ACK的意思就是:Consumer说:ok,我消费成功了。这条消息给我标记成已消费吧。
七、消费模式
1、集群模式(Clustering)
1.1、图解
1.2、特点
-
每条消息只需要被处理一次,broker只会把消息发送给消费集群中的一个消费者
-
在消息重投时,不能保证路由到同一台机器上
-
消费状态由broker维护
2、广播模式(Broadcasting)
2.1、图解
2.2、特点
-
消费进度由consumer维护
-
保证每个消费者都消费一次消息
-
消费失败的消息不会重投
八、RocketMQ - API :https://blog.csdn.net/My_SweetXue/article/details/107381276