- MQ实现
- ActiveMQ
- RabbitMQ
- RocketMQ
- Kafka
- Redis
- MQ理论框架
- 消息类型
- 普通消息
- 事务消息
- 定时和延时消息
- 顺序消息
- 消息特性
- 消息重试
- 消息幂等
- 路由中心NameServer
-
NameServer架构设计
-
NameServer集群
-
Producer集群
-
Consumer集群
-
Broker
-
Master...n
-
Slave...n
-
-
Consumer集群
-
-
NameServer启动流程
-
NameServer启动类:org.apache.rocketmq.namesrv.NamesrvStartup
-
Step 1 :解析配置文件,填充NameServerConfig(业务参数)、NettyServerConfig(网络参数)属性值
-
参数来源
-
-c configFile 通过 -c 命令指定配置文件的路径
-
使用 “--属性名 属性值”,例如 --listenPort 9876
-
-
-
Step 2:根据启动属性创建NamesrvController实例,并初始化该实例,NameServerController实例为NameServer核心控制器
-
加载KV配置,创建NettyServer网络处理对象,然后开启两个定时任务
-
定时任务1:NameServer每隔10s扫描一次Broker,移除处于不激活状态的Broker
-
定时任务2:NameServer每隔10分钟打印一次KV配置
-
-
-
Step 3:注册JVM钩子函数并启动服务器,以便监听Broker、消息产生者的网络请求
-
-
NameServer路由注册、故障剔除
-
路由元信息
-
NameServer路由实现类:org.apache.rocketmq.namesrv.routeinfo.RouteInfoManager
-
topicQueueTable:Topic消息队列路由信息,消息发送时根据路由表进行负载均衡。
-
private final HashMap<String/* topic */, List<QueueData>> topicQueueTable;
-
QueueData
-
private String brokerName;
-
private int readQueueNums;
-
private int writeQueueNums;
-
private int perm;
-
private int topicSynFlag;
-
-
-
-
brokerAddrTable:Broker基础信息,包含brokerName、所属集群名称、主备Broker地址。
-
private final HashMap<String/* brokerName */, BrokerData> brokerAddrTable;
-
BrokerData
-
private String cluster;
-
private String brokerName;
-
private HashMap<Long/* brokerId */, String/* broker address */> brokerAddrs
-
-
-
-
clusterAddrTable:Broker集群信息,存储集群中所有Broker名称。
-
private final HashMap<String/* clusterName */, Set<String/* brokerName */>> clusterAddrTable;
-
-
brokerLiveTable:Broker 状态信息。NameServer每次收到心跳包时会替换该信息。
-
BrokerLiveInfo
-
private Long lastUpdateTimestamp;
-
private DataVersion dataVersion;
-
private Channel channel;
-
-
-
filterServerTable:Broker上的FilterServer 列表,用于类模式消息过滤。
-
-
路由注册
-
RocketMQ 路由注册是通过Broker与NameServer的心跳功能实现的。Broker启动时向集群中所有的NameSer发送心跳语句,每隔30s向集群中所有NameServer发送心跳包,NameServer收到Broker心跳包时会更新borkerLiveTable缓存中BrokerLiveInfo的lastUpdateTimestamp,然后Name Server 每隔10s扫描brokerLiveTable,如果连续120s没有收到心跳包,NameServer将移除该Broker的路由信息同时关闭Socket连接。
-
Broker发送心跳包
-
NameServer处理心跳包
-
org.apache.rocketmq.namesrv.processor.DefaultRequestProcessor网络处理器解析请求类型,如果请求类型为RequestCode.REGISTER_BROKER,则请求最终转发到RouteInfoManager#registerBroker。
-
Step1:路由注册需要加写锁,防止并发修改RouteInfoManager中的路由表。首先判断Broker所属集群是否存在,如果不存在,则创建,然后将broker名加入到集群Broker集合中
-
java并发锁ReentrantReadWriteLock读写锁源码分析
-
共享锁
-
排他锁
-
CLH算法
-
-
-
Step 2:维护BrokerData信息,首先从brokerAddrTable根据BrokerName尝试获取Broker信息,如果不存在,则新建BrokerData并放入到brokerAddrTable,registerFirst设置为true;如果存在,直接替换原先的,registerFirst设置为false,表示非第一次注册。
-
Step 3:如果Broker为Master,并且Broker Topic配置信息发生变化或者是初次注册,则需要创建或更新Topic路由元数据,填充topicQueueTable,其实就是为默认主题自动注册路由信息,其中包含MixAll.DEFAULT_TOPIC的路由信息。当消息产生者发送主题时,如果该主题未创建并且BrokerConfig的autoCreateTopicEnable为true时,将返回MixAll.DEFAULT_TOPIC的路由信息。
-
Step 4:更新BrokerLiveInfo。存活Broker信息表,BrokeLiveInfo是执行路由删除的重要依据。
-
Step 5:注册Broker的过滤器Server的地址列表,一个Broker上会关联多个FilterServer消息过滤服务器。如果此Broker为从节点,则需要查找该Broker的Master的节点信息,并更新对应的masterAddr属性。
-
-
-
路由删除
-
触发路由删除的触发点
-
NameServer定时扫描brokerLiveTable检测上次心跳包与当前系统时间的时间差,如果时间大于120s,则需要移除该Broker信息。
-
Broker在正常被关闭的情况下,会执行unregisterBroker指令。
-
-
-
路由发现
-
RocketMQ路由发现是非实时额,当Topic路由出现变化后,NameServer不主动推送给客户端,而是由客户端定时拉去主题最新的路由。
-
-
-
-
消息发送
-
发送方式
-
同步(sync):发送者向MQ执行发送消息API时,同步等待,直到消息服务器返回发送结果。
-
异步(async):发送者向MQ执行发送消息API时,指定消息发送成功后的回调函数,然后调用消息发送API后,立即返回,消息发送者线程不阻塞,直到运行结束,消息发送成功或失败的回调任务在一个新的线程中执行。
-
单向(oneway):消息发送者向MQ执行发送消息API时,直接返回,不等待消息服务器的结果,也不注册回调函数,简单地说,就是只管发,不在乎消息是否成功存储在消息服务器上。
-
-
消息队列如何进行负载?
-
消息发送如何实现高可用?
-
批量消息发送如何实现一致性?
-
-
RocketMQ消息
-
org.apache.rocketmq.common.message.Message
-
private String topic; // 主题
-
private int flag; // 消息Flag(RocketMQ不做处理)
-
private Map properties; // 扩展属性
-
private byte[]; // 消息体
-
public Message(String topic, byte[])
-
public Message(String topic, String tags, String keys /* Message索引键,多个用空格隔开,RocketMQ可以根据这些key快速检索到消息。 */ , int flag, byte[], boolean waitStoreMsgOK /* 消息发送时是否等消息存储完成后再返回。 */)
-
public Message(String topic, String tags, byte[])
-
public Message(String topic, String tags, String keys, byte[])
-
public void setKeys(String keys)
-
public void putUserProperty(final String name, final String value)
-
public int getDelayTimeLevel()
-
public void setDelayTimeLevel(int level/* 消息延迟级别,用于定时消息或消息重试。*/)
-
-
-
生产者启动流程
-
DefaultMQProducer消息发送者
-
void createTopic(String key, String newTopic, int queueNum, int topicSysF!ag)
-
创建主题。
-
key:目前未实际作用,可以与newTopic相同。
-
newTopic:主题名称。
-
queueNum:队列数量。
-
topicSysFlag:主题系统标签,默认为0。
-
-
long searchOffset(final MessageQueue mq, final long timestamp)
-
根据时间戳从队列中查找其偏移量。
-
-
long maxOffset(final MessageQueue mq)
-
查找该消息队列中最大的物理偏移量
-
-
long minOffset(final MessageQueue mq)
-
查找该消息队列中最小的物理偏移量
-
-
MessageExt viewMessage(final String offsetMsgld)
-
根据消息偏移量查找消息
-
-
QueryResult String topic, final String key, final int maxNum, final long begin, final long end)
-
根据条件查询消息。
-
topic:消息主题。
-
key:消息索引字段
-
maxNum:本次最多取出消息条数
-
begin:开始时间。
-
end:结束时间。
-
-
-
消息生产者启动流程
-
消息发送基本流程
-
验证消息
-
查找路由
-
消息发送(包含异常处理机制)
-
-
-
事务消息
-
事务消息实现思想
-
两阶段提交
-
定时事务状态回查
-
-
事务消息发送流程
-
事务消息提交或回滚
-
事务消息回查事务状态
-
MQ入门知识点集合
最新推荐文章于 2024-04-13 09:44:10 发布