一:启动NameServer
启动NameServer,NameServer启动后开始监听端口,等待BrokerServer、Producer、Consumer连接
二:启动BrokerServer
启动BrokerServer的时候,BrokerServer会与配置好的NameServer列表的所有节点建立长链接,然后每隔30秒想NameServer定时发送心跳包
三:创建Topic
可以先创建Topic,创建Topic是需要指定Topic要存储在那些BrokerServer上,当然在创建Topic时也会将Topic与BrokerServer的关系写入到NameServer中,不过,这是可选项们也可以在消息发送的时候自动创建Topic
四:Producer发送消息
Producer发送消息,启动时先很NameServer集群中的其中一台建立长链接,并从NameServer中获取路由信息,即当前发送的Topic的Queue与BrokerServer的地址(ip+port)的映射关系,然后根据算法策略从Topic下队列中选择一个Queue(默认轮询发送),与队列所在的BrokerServer建立长链接从而向BrokerServer发消息,当然,在获取路由信息后Producer会首先将路由信息缓存到本地,在每隔30秒从NameServer中更新一次路由信息
生产流程如下
- Producer发送消息之前,先向NameServer发出获取Topic的路由信息的请求
- NameServer返回Topic的路由表以及Broker列表
- Producer根据代码中指定的Queue选择策略,从Queue列表中选择一个队列,用于后续存储消息
- Producer对消息而外处理,如批量消息,如消息超过4M,则会对消息做压缩处理
- Producer想选择出的Queue所在的Broker发出Rpc请求,将消息发送到选择的Queue
路由表
实际上就是一个Map,key为Topic的名字,value是QueueData实例列表,QueueData并不是一个Queue对应一个QueueData,而是一个Broker中该Topic的所有Queue对应一个QueueData,即,只要涉及到该Topic的Broker,一个Broker对应一个QueueData,QueueData中包含BrokerName,简单来说,路由表的key为Topic名称,value则为所有涉及该Topic的Broker列表
Broker列表
Broker列表,其实际上也是一个Map,key为BrokerName,value为BrokerData,一个Broker对应一个BrokerData实例,对吗?显然不是的,一套BrokerName名称相同的Master Slave小集群对应一个BrokerData,BrokerData中包含BrokerName以及一个Map,该Map的key为BrokerId,value为该Broker对应的地址,BrokerId为0代表为Master,非0代表Salve
结构
五:Consumer消费消息
Consumer根Producer类似,启动时跟一台NameServer建立长链接,获取其所订阅的Topic路由信息,然后根据算法策略从路由中获取到其所要消费的Queue,然后直接根据BrokerServer建立长链接,开始消费其中的消息,Consumer在获取到路由信息后,同样也会每隔30秒从NameServer更新一次路由信息,不过不同于Producer的是,Consumer还会想BrokerServer发送心跳,以确保BrokerServer的存活状态