话接上篇RocketMQ学习笔记(一)
笔记一是带着几个问题去做学习记录的,问题如下:
1.为什么要引用MQ?
2.MQ能做什么?
3.确定引入后怎么选择合适的MQ?
4.引入MQ后带来哪些新的问题?
5.IDEA怎么编译RocketMQ源码
其中重点内容还是在初步了解MQ的特性和使用场景,并没有针对引用MQ后所带来的新问题进行深入的探究。
因此,本篇笔记将先通过认识RocketMQ源码各个模块的作用及工作原理来进一步了解RocketMQ,最后就是探究引用MQ后带来的新问题以及解决建议。
一、认识RocketMQ
(1) 核心模块功能介绍:
acl(权限控制):
1.控制第一级别资源topic的客户端访问权限,通过RPCHook注入AccessKey和SecretKey签名
broker(消息中转站):
1.单个broker与所有namesrv保持长连接,每隔30s(无法更改)给所有的namesrv上报一次心跳,心跳中包含自身的topic配置
2.用于接收生产者发来的消息,并调用store层服务对消息进行存储,支持同步双写,异步双写等模式
3.提供push/pull接口来进行消息拉取处理
client(客户端API):
1.提供发送、接受消息的客户端API
common(通用组件):
1.公用的方法、类、配置文件、常量等
filter(消息过滤):
1.在broker端实现,针对生产者发送来的消息进行过滤,可以根据自己的过滤需求定制过滤协议
namesrv(消息调度中心):
1.无状态,集群环境下节点间完全独立,无交互(每个实例的数据均相同)
2.保存topicName,管理topic的路由信息、队列、broker实时配置等元数据
3.每隔10秒钟(此时间无法更改)就会扫描所有还存活的broker连接,若某个连接2分钟内(当前时间与最后更新时间差值超过2分钟,此时间无法更改)没有发送心跳数据,则断开此连接,一旦断开,nameserver会立即感知并更新topc与队列的对应关系,并不会通知生产者和消费者
4.其它模块通过Nameserv提供的接口获取最新的Topic配置和路由信息
remoting(内部通信服务):
1.RocketMQ内部模块之间的所有通信服务都是通过remoting
2.由Netty+FastJson(序列化)来实现
store(存储):
存储消息和索引
tools(工具):
命令行工具
(2) 重点分析:
1.RocketMQ之大脑NameServer
问题:
为什么需要NameServer ?
背景:
公司项目中为了避免消息服务单点故障导致整个系统崩溃,一般都会将消息服务器进行集群部署,让多台消息服务器共同去存储消息
存在的问题:
1.在集群环境中就会造成生产者不知道将消息往哪台消息服务器中发送
2.如果一台消息服务器宕机了,如何在不重启服务的情况下去感知存活的有哪些节点
为了解决以上问题,所以我们需要一个像大脑一般的监管调度中心NameServer去帮助感知机体(节点或服务)是否可用,检测机体是否存活,避免做无用功
重要性:
1.Broker消息服务器在启动时会一对多的在所有NameServer中进行注册,并建立长连接,消息生产者(Producer)在发送消息之前先从NameServer获取Broker服务器地址列表,然后根据负载算法从列表中选择一台合适的消息服务器进行消息发送
2.消费者启动后会一对一的跟NameServer建立长连接,并获取NameServer中已注册的Broker地址列表,选择自己感兴趣(订阅)的broker,拉取消息进行消费
由此可以看出,无论是消息服务注册、消费者订阅消息、还是生产者获取服务器地址都和NameServer息息相关,其扮演者最关键的角色!
2.RocketMQ之基石Broker
问题:
为什么称Broker为基石?
分析:
Broker的作用为接收请求、服务端过滤、消息持久化、存储元素据(偏移量offset、消费订阅组Group、消息队列ConsumeQueue、主题topic、索引index等)、以及消息处理等
可以说Broker为构建消息服务、持久化消息、处理消费等核心模块提供了全方位的配置和指引,也是我们RocketMQ的主要核心工作站
3.看看核心工作流程(非原创):
(3) 角色名词:
Producer:
生产者,负责产生消息,通过负载均衡选择合适的Broker队列进行消息投递,业务系统大多扮演该角色
Consumer:
消费者,消息的订阅方订阅关注的Topic,以获取并消费消息,提供push/pull两种方式(实际均为pull)拉取消息,群组消费时也提供集群和广播两种模式,通常是后台系统负责异步消费
Message Queue:
消息队列,可以理解为具有某些共同特性的一组消息形成的队列,可以看作一个数组,只是这个数组长度理论上无限,数组的下标index,就是偏移量offset,一个topic下可以含有多个MessageQueue,队列中只保存最近几天的数据,以前的数据会按照过期删除来处理
Offset:
偏移量,用于记录偏移位置
CommitLog:
消息持久化的物理文件
CommitLog、offset、Consumer Queue三者关系:
Topic:
可以看作一种分类(一级分类),将具有某些相同特性的消息归类于同一个集合,topic与生产者、消费者的关系均为多对多
Tag:
同topic一样也作为一种分类(二级分类),只是其在topic下将同一个topic的消息再根据更细节的过滤条件进行筛选分类
Push Consumer:
Consumer的一种,一般会为Consumer对象注册一个 Listener 接口,一旦收到消息,Consumer对象立刻回调 Listener 接口方法
Pull Consumer:
Consumer的一种,用于调用Consumer的拉消息方法,从Broker中拉取消息
Producer Group:
一类Producer的集合,该类Producer通常发送同一类消息,且逻辑一致
Consumer Group:
一类Consumer的集合,该类Consumer通常消费同一类消息,且逻辑一致
(4) 消息收发:
RocketMQ支持发布和订阅模型,消息生产者创建Topic并将消息发送到Topic,消费者会对感兴趣的Topic进行订阅以便从其接收消息,通信可以是一对多(扇出)、多对一(扇入)和多对多
生产者集群:生产消息的集群,一个生产者集群下包含多个生产者实例,可以发送多个Topic消息
消费者集群:消费消息的集群,一个消费者集群下包含多个消费者实例,集群模式下多个消费者以均摊方式消费消息,广播方式下,消费者集群下的每个实例都要消费全量数据
二、认识消息和消费
顺序消息:
消费消息的顺序与发送消息的顺序一致,在 RocketMQ 中,主要指的是局部顺序,即一类消息为满足顺序性,必须由Producer单线程顺序发送到同一个队列,然后Consumer就可以按照发送的顺序进行消费
普通顺序消息:
顺序消息的一种,一般可以保证完全的顺序消息,但是一旦发生通信异常,Broker 重启,导致队列总数发生变化,哈希取模后定位的队列也会随之改变,会产生短暂的消息顺序不一致
严格顺序消息:
顺序消息的一种,无论在正常或异常情况下,都能保证顺序,但却牺牲了Failover(失败转移)的特性,服务可用性大大降低,集群中,可以通过将服务器部署为同步双写模式,由备机自动切换为主避免来解决,不过仍会存在几分钟的服务不可用时间,所以非必要不建议使用这种消息,当前已知只有数据库binlog同步时强依赖于严格顺序消息
广播消费:
当使用广播消费模式时,RocketMQ会将每条消息推送给集群内所有注册过的消费者,保证消息至少被每个消费者消费一次,适用于消费端集群化部署,每条消息需要被集群下的每个消费者处理的场景
注意:
1.广播模式下不支持顺序消息、不支持重置消费位点
2.每条消息都需要被相同订阅逻辑的多台机器处理、消费进度在客户端维护,出现重复消费的概率稍大于集群模式
3.消费失败后不会重投消费失败的消息,因此业务方需要关注消费失败的情况,每一次重启都会从最新消息消费
4.RocketMQ控制台不支持消息堆积查询、消息堆积报警和订阅关系查询功能
集群消费:
当使用集群消费模式时,RocketMQ会认为任意一条消息只需要被集群内的任意一个消费者处理即可,因此每一条消息都只会被分发到一台机器上处理,适用于消费端集群化部署,每条消息只需要被处理一次的场景
注意:集群消费模式中不保证每一次失败重投的消息路由到同一台机器上
我还是低估了RocketMQ的知识量,写到现在还没把最基本的知识点理透,以上内容来自PDF,阿里服务区以及大佬博客有些乱。
那天咨询了一个将MQ知识学的差不多的滴滴大佬,他给的意见是学习一定要去看书,不要盲目的去百度乱七八糟的博客,因为博客的东西都是不完整也不够权威的,他建议要么官网,要么权威出版书
因此,我打算结束这篇笔记,下一篇会跟着《RocketMQ 技术内幕》这本PDF和部分阿里服务社区和官网来学习,并记录
好了,最后还是叮嘱自己,破脑子敌不过烂笔头!