看完此文章,你基本可以理解RocketMQ并进行项目使用了。那里有不足,欢迎评论指正。
1. MQ基本介绍
MQ好处: 1.应用解耦 2.流量削锋: 请求流量瞬间猛增,可能会把系统压垮。MQ可以将请求缓存起来,分散到很长一段时间去处理。提高系统的稳定性。 3.数据分发
缺点: 1.MQ宕机了,对业务造成影响 2.消息重复消费问题,消息丢失问题,消息的顺序性问题 3.数据一致性问题
2. RocketMQ基本介绍
RocketMQ是由阿里捐赠给Apache的一款分布式、队列模型的开源消息中间件。RocketMQ单机吞吐量 10万级的。
RocketMQ主要由 Producer、Broker、Consumer 三部分组成,其中Producer 负责生产消息,Consumer 负责消费消息,Broker 负责存储消息。Broker 在实际部署过程中对应一台服务器,每个 Broker 可以存储多个Topic的消息,每个Topic的消息也可以分片存储于不同的 Broker。Message Queue 用于存储消息的物理地址,每个Topic中的消息地址存储于多个 Message Queue 中。ConsumerGroup 由多个Consumer 实例构成。
具体详细介绍查看 https://github.com/apache/rocketmq/tree/master/docs/cn
broker:Broker主要负责消息的存储、投递和查询以及服务高可用保证。类似一个邮局;broker向每个nameserver都要上报信息。 nameServer:NameServer是一个非常简单的Topic路由注册中心,其角色类似Dubbo中的zookeeper,支持Broker的动态注册与发现管理broker。类似各个邮局的管理机构;无状态的,每一个节点的信息都是一样的;节点之间无消息同步 topic:消息的类别 message Queue:topic的分区
broker 主动上报到nameServer 生产者发送消息到broker 消费者从broker获取消息 生产者和消费者,询问nameServer分配的broker是谁
3. 集群架构
集群工作流程:
- 启动NameServer,NameServer起来后监听端口,等待Broker、Producer、Consumer连上来,相当于一个路由控制中心。
- Broker启动,跟所有的NameServer保持长连接,定时发送心跳包。心跳包中包含当前Broker信息(IP+端口等)以及存储所有Topic信息。注册成功后,NameServer集群中就有Topic跟Broker的映射关系。
- 收发消息前,先创建Topic,创建Topic时需要指定该Topic要存储在哪些Broker上,也可以在发送消息时自动创建Topic。
- Producer发送消息,启动时先跟NameServer集群中的其中一台建立长连接,并从NameServer中获取当前发送的Topic存在哪些Broker上,轮询从队列列表中选择一个队列,然后与队列所在的Broker建立长连接从而向Broker发消息。
- Consumer跟Producer类似,跟其中一台NameServer建立长连接,获取当前订阅Topic存在哪些Broker上,然后直接跟Broker建立连接通道,开始消费消息。
brokerID为0,代表master,不是0为slave
集群模式 : 单Master模式 多Master模式 多Master多Slave模式(异步) 多Master多Slave模式(同步)
4. broker-a.properties配置文件说明
#所属集群名字 brokerClusterName=rocketmq-cluster #broker名字,不同的配置文件填写的不一样。 brokerName=broker-a #0 表示 Master,>0 表示 Slave brokerId=0 #nameServer地址,分号分割 namesrvAddr=192.168.182.124:9876;192.168.182.125: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/rocketmq/store #commitLog 存储路径 storePathCommitLog=/usr/local/rocketmq/store/commitlog #消费队列存储路径存储路径 storePathConsumeQueue=/usr/local/rocketmq/store/consumequeue #消息索引存储路径 storePathIndex=/usr/local/rocketmq/store/index #checkpoint 文件存储路径 storeCheckpoint=/usr/local/rocketmq/store/checkpoint #abort 文件存储路径 abortFile=/usr/local/rocketmq/store/abort #限制的消息大小 maxMessageSize=65536 #flushCommitLogLeastPages=4 #flushConsumeQueueLeastPages=2 #flushCommitLogThoroughInterval=10000 #flushConsumeQueueThoroughInterval=60000 #Broker 的角色 #- ASYNC_MASTER 异步复制Master #- SYNC_MASTER 同步双写Master #- SLAVE brokerRole=SYNC_MASTER #刷盘方式 #- ASYNC_FLUSH 异步刷盘 #- SYNC_FLUSH 同步刷盘 flushDiskType=ASYNC_FLUSH #checkTransactionMessageEnable=false #发消息线程池数量 #sendMessageThreadPoolNums=128 #拉消息线程池数量 #pullMessageThreadPoolNums=128
5. 安装
5.1 下载安装包解压
地址:https://github.com/apache/rocketmq/releases
rocketmq-all-4.4.0-bin-release.zip
5.2 修改内存
vi runbroker.sh vi runserver.sh
它默认是8G,所以改小一点
5.3 启动nameServer
nohup sh bin/mqnamesrv >/dev/null 2>&1 &
查看日志
tail -f /root/logs/rocketmqlogs/namesrv.log
5.4 启动broker
nohup sh bin/mqbroker -n 192.168.182.124:9876 -c conf/broker.conf >/dev/null 2>&1 &
查看日志
tail -f /root/logs/rocketmqlogs/broker.log
5.5 关闭服务
关闭namesrv服务:
sh bin/mqshutdown namesrv
关闭broker服务 :
sh bin/mqshutdown broker
5.6 安装可视化插件
RocketMQ有一个对其扩展的开源项目rocketmq-externals,这个项目中有一个子模块叫“rocketmq-console”,这个便是管理控制台项目了。下载项目进行配置,然后maven打成jar包进行部署。
具体详见我写的部署文档
6. 项目进行集成
6.1 客户端使用
<dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>4.3.0</version> </dependency>
具体使用详见:https://github.com/apache/rocketmq/blob/master/docs/cn/RocketMQ_Example.md
6.2 springboot集成
<dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> <version>2.0.3</version> </dependency>
使用rocketMQTemplate
6.3 spring cloud alibaba集成
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-stream-rocketmq</artifactId> </dependency>
使用Spring Cloud Stream 是一个用于构建基于消息的微服务应用框架。 基于 SpringBoot 创建具有生产级别的单机 Spring 应用,并且使用 Spring Integration 与 Broker 进行连接。
详见实例:https://github.com/lijinliang83/rocketmq-examples(是自己上传的实例,项目使用没有问题)
7. 发送模式和消费模式
(1)生产者发送消息,会采用轮询的方式发送到不同的message queue。queue落在不同的broker当中。所以消息发送到不同的broker中。
(2)消费者消费消费消息,广播模式和负载均衡模式,默认是负载均衡模式,启动多个消费者即可
8. 消息的高可用
(1)消息发送的高可用 创建topic,创建在多个broker组上(相同的broker名称,不同的brokerId的机器组装一个broker组)。 当一个组的master不可用,其他组的master仍可用。生产者仍然可以发送消息
(2)消息消费的高可用 Master不可用繁忙的時候,consumer会自动切换到slave读取。这个不用配置,是自动切换的机制。
9. 消息存储
消息存储整体架构是 (1) CommitLog:消息主体以及元数据的存储主体,存储Producer端写入的消息主体内容,消息内容不是定长的。单个文件大小默认1G 。消息主要是顺序写入日志文件,当文件满了,写入下一个文件。
(2) ConsumeQueue:消息消费队列,引入的目的主要是提高消息消费的性能。Consumer即可根据ConsumeQueue来查找待消费的消息。其中,ConsumeQueue(逻辑消费队列)作为消费消息的索引,保存了指定Topic下的队列消息在CommitLog中的起始物理偏移量offset,消息大小size和消息Tag的HashCode值。consumequeue文件可以看成是基于topic的commitlog索引文件
(3) IndexFile:IndexFile(索引文件)提供了一种可以通过key或时间区间来查询消息的方法。Index文件的存储位置是:$HOME \store\index${fileName},文件名fileName是以创建时的时间戳命名的,固定的单个IndexFile文件大小约为400M,一个IndexFile可以保存 2000W个索引,IndexFile的底层存储设计为在文件系统中实现HashMap结构,故rocketmq的索引文件其底层实现为hash索引。
10. 刷盘机制
消息写入,有俩种方式: 分布式同步刷盘,写入内存,写入磁盘,再进行返回。保证消息的可靠性 分布式异步刷盘 ,写入内存直接返回。提高消息发送的吞吐量
11. 消息的主从复制
同步复制:master和slave均写成功,然后再返回给客户端成功状态。缺点:降低系统吞吐量,有延迟。 异步复制:消息发送给master,直接返回客户端成功状态。slave异步复制数据。如果master挂掉,数据可能会丢失。系统吞吐量高。没有延迟。
12. 死信队列
消息消费失败,然后重试,达到最大重试次数,仍然失败。不会立刻丢弃,放到消费者的特殊队列中。 不会再被消费者正常消费,3天后会进行自动删除。
一个死信队列不是针对某个消费者,是针对某个消费者组。
13. 消费幂等性
可以设置key去实现