添加了注释的源码
https://github.com/WangTingYeYe/rocketmq_source

先来一张总体的源码流程:

前提

请大家先浏览我前面转载的官网的一些rocketmq的基本概念和架构设计之后再阅读本文。

NameServer 是什么

  • 官网解释:
    NameServer 充当路由消息的提供者。生产者或消费者能够通过名字服务查找各主题相应的Broker IP列表。多个Namesrv实例组成集群,但相互独立,没有信息交换。

  • 白话文:
    生产者和消费者怎么知道每个broker的地址以及broker上消息分别存放在集群中的那台机器上?
    NameServer就是为了解决这个,可以理解为就是一个数据库。
    NameServer集群之间的服务是没有任何的信息交互的

NameServer 启动流程

分析一个中间件的启动入口,第一步应该看他的启动脚本。

mqnamesrv

#!/bin/sh# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.if [ -z "$ROCKETMQ_HOME" ] ; then## resolve links - $0 may be a link to maven's homePRG="$0"# need this for relative symlinkswhile [ -h "$PRG" ] ; dols=`ls -ld "$PRG"`link=`expr "$ls" : '.*-> \(.*\)$'`if expr "$link" : '/.*' > /dev/null; thenPRG="$link"elsePRG="`dirname "$PRG"`/$link"fidonesaveddir=`pwd`ROCKETMQ_HOME=`dirname "$PRG"`/..# make it fully qualifiedROCKETMQ_HOME=`cd "$ROCKETMQ_HOME" && pwd`cd "$saveddir"
fiexport ROCKETMQ_HOMEsh ${ROCKETMQ_HOME}/bin/runserver.sh org.apache.rocketmq.namesrv.NamesrvStartup $@

runserver.sh

#!/bin/sh# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.#===========================================================================================
# Java Environment Setting
#===========================================================================================
error_exit ()
{echo "ERROR: $1 !!"exit 1
}[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=$HOME/jdk/java
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/java
[ ! -e "$JAVA_HOME/bin/java" ] && error_exit "Please set the JAVA_HOME variable in your environment, We need java(x64)!"export JAVA_HOME
export JAVA="$JAVA_HOME/bin/java"
export BASE_DIR=$(dirname $0)/..
export CLASSPATH=.:${BASE_DIR}/conf:${BASE_DIR}/lib/*:${CLASSPATH}#===========================================================================================
# JVM Configuration
#===========================================================================================
# The RAMDisk initializing size in MB on Darwin OS for gc-log
DIR_SIZE_IN_MB=600choose_gc_log_directory()
{case "`uname`" inDarwin)if [ ! -d "/Volumes/RAMDisk" ]; then# create ram disk on Darwin systems as gc-log directoryDEV=`hdiutil attach -nomount ram://$((2 * 1024 * DIR_SIZE_IN_MB))` > /dev/nulldiskutil eraseVolume HFS+ RAMDisk ${DEV} > /dev/nullecho "Create RAMDisk /Volumes/RAMDisk for gc logging on Darwin OS."fiGC_LOG_DIR="/Volumes/RAMDisk";;*)# check if /dev/shm exists on other systemsif [ -d "/dev/shm" ]; thenGC_LOG_DIR="/dev/shm"elseGC_LOG_DIR=${BASE_DIR}fi;;esac
}choose_gc_options()
{# Example of JAVA_MAJOR_VERSION value : '1', '9', '10', '11', ...# '1' means releases befor Java 9JAVA_MAJOR_VERSION=$("$JAVA" -version 2>&1 | sed -r -n 's/.* version "([0-9]*).*$/\1/p')if [ -z "$JAVA_MAJOR_VERSION" ] || [ "$JAVA_MAJOR_VERSION" -lt "9" ] ; thenJAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"JAVA_OPT="${JAVA_OPT} -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:-UseParNewGC"JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:${GC_LOG_DIR}/rmq_srv_gc_%p_%t.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps"JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m"elseJAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0"JAVA_OPT="${JAVA_OPT} -Xlog:gc*:file=${GC_LOG_DIR}/rmq_srv_gc_%p_%t.log:time,tags:filecount=5,filesize=30M"fi
}choose_gc_log_directory
choose_gc_options
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"
JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages"
#JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n"
JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}"
JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}"$JAVA ${JAVA_OPT} $@

可以看到 最后就是 执行了
java org.apache.rocketmq.namesrv.NamesrvStartup

启动类

org.apache.rocketmq.namesrv.NamesrvStartup#main

思考

基于NameServer 的功能思考一下我们自己写的话会需要哪些东西?

  • 要读取用户指定的一些配置
  • 开启网络io用于接受生产者、消费者的服务发现。broker的注册
  • 心跳监测剔除不活跃的服务
  • 处理消费者和生产者的服务发现逻辑
  • 处理broker的注册逻辑

要读取用户指定的一些配置

通过NamesrvConfig和NettyServerConfig两个对象来包装对应的NameServer的配置

这里很明显直接设置了服务端口为9876

下面的代码就是将命令行中指定的配置和配置文件的配置塞到这两个对象里面

最后将两个对象包装为一个NamesrvController对象,他就是用来代表NameServer的一切

开启网络io用于接受生产者、消费者的服务发现。broker的注册

此处初始化了一个NettyRemotingServer从名字上就可以看出这个就是用来与外界进行网络io的组件



这里注册了一个DefaultRequestProcessor 处理对象。后面用于处理请求

心跳监测剔除不活跃的服务

开启了一个线程单独去扫描所有的broker注册表(就是对比的broker发送的最后一次心跳时间)

broker注册、生产消费者的服务发现

前面remotingServer里面注册了一个DefaultRequestProcessor。
跟随代码发现。当nettry服务接收到请求后会交给DefaultRequestProcessor来处理

根据req.code 来分发请求处理逻辑。

broker注册的处理逻辑

总结:

从整个流程中我们可以提取出一些关键信息:

  • 通过RemotingServer (nettry服务)来接受请求
  • 接受到请求后会通过DefaultRequestProcessor根据请求code分发处理
  • RouteInfoMapper 管理了路由信息,保存了注册上来的broker信息
  • NamesrvConfig、NettyServerConfig 保存了网络和NettyServer的核心配置
  • NamesrvController 是整个NameServer的核心。整合了上面的一切

rocketmq源码①-NameServer是什么以及他的启动流程相关推荐

  1. 深入剖析RocketMQ源码-NameServer

    作者:vivo互联网服务器团队-Ye Wenhao 一.RocketMQ架构简介 1.1 逻辑部署图 (图片来自网络) 1.2 核心组件说明 通过上图可以看到,RocketMQ的核心组件主要包括4个, ...

  2. OpenJDK源码赏析之二:java虚拟机启动流程到首函数调用全流程

    承接上一谈 OpenJDK源码赏析之一:漫谈java的历史渊源_星空_AZ的博客-CSDN博客 JAVA从启动到第一个函数执行的发生的流程: WinMain->JLI_Launch->JV ...

  3. Android 12系统源码_SystemUI(一)SystemUI的启动流程

    前言 Android 的 SystemUI 其实就是 Android 的系统界面,它包括了界面上方的状态栏 status bar,下方的导航栏Navigation Bar,锁屏界面 Keyguard ...

  4. Android 9.0系统源码_SystemUI(一)SystemUI的启动流程

    一.SystemUI 介绍 1.初步认识SystemUI Android 的 SystemUI 其实就是 Android 的系统界面,它包括了界面上方的状态栏 status bar,下方的导航栏Nav ...

  5. 《RocketMQ源码分析》NameServer如何处理Broker的连接

    <RocketMQ源码分析>NameServer如何处理Broker的连接 NameServer 介绍 NameServer 功能 动态路由发现和注册 服务剔除 创建NameServerC ...

  6. RocketMQ源码学习

    RocketMQ源码学习 文章目录 RocketMQ源码学习 Producer 是怎么将消息发送至 Broker 的? 同步发送 异步发送 队列选择器 事务消息 原理 Broker 是怎么处理客户端发 ...

  7. RocketMQ 源码学习笔记 Producer 是怎么将消息发送至 Broker 的?

    RocketMQ 源码学习笔记 Producer 是怎么将消息发送至 Broker 的? 文章目录 RocketMQ 源码学习笔记 Producer 是怎么将消息发送至 Broker 的? 前言 项目 ...

  8. 结合RocketMQ 源码,带你了解并发编程的三大神器

    摘要:本文结合 RocketMQ 源码,分享并发编程三大神器的相关知识点. 本文分享自华为云社区<读 RocketMQ 源码,学习并发编程三大神器>,作者:勇哥java实战分享. 这篇文章 ...

  9. 6、RocketMQ 源码解析之 Broker 启动(上)

    上面一篇我们介绍了 RocketMQ 的元数据管理,它是通过自定义一个 KV 服务器.并且其它服务在 NameServer 注册服务信息的时候都是全量注册.如果 RocketMQ 的拓扑图当中有多台 ...

最新文章

  1. 给你一个亿的keys,Redis如何统计?
  2. 用74LS161构建多位计数器Multisim仿真实验
  3. Ubuntu12下安装redis(多图版)+ Jedis连接Redis
  4. softmax理论及代码解读——UFLDL
  5. Firefox搜索框:自动出现添加搜索的提示
  6. NSX控制平面和静态路由更新流程1
  7. Docker 安装 weblogic12c
  8. JavaScript的apply和call方法及其区别
  9. matlab在二值图像上画曲线_数字图像处理:Image Printing Program Based on Halftoning
  10. 服务器子接口配置的几种方式:子接口模式、vlan模式
  11. 前往庄园失败 当前服务器不稳定,摩尔庄园手游登录不了是怎么回事 摩尔庄园手游登录失败怎么办...
  12. 射手播放器的 clientkey
  13. mandriva2010 xp ubuntu10.04 三系统的安装
  14. Xshell6复制粘贴快捷设置
  15. uniapp之安卓使用高德地图
  16. 【Web前端】【疑难杂症】轮播图图片自适应显示问题(bootstrap3轮播图)
  17. Process Hacker 简单介绍
  18. 软件工程毕业论文mysql英文翻译_软件工程专业毕业设计外文文献翻译
  19. ua识别(浏览器标识识别)
  20. Smartbanner: Intelligent banner design framework that strikes a balance between freedom and rules

热门文章

  1. 自动检测文本文件编码是否为GB2312(简体中文),并转换为UTF8编码,附一个GB2312全区对应的utf8编码码表
  2. 【测控电路】三运放高共模抑制比放大电路
  3. react 点击弹窗之外关闭弹窗 demo
  4. 联想Y700笔记本:硬盘突然不见了
  5. 基于大数据分析的安全管理平台技术研究及应用
  6. PTA 7-75 正方体表面积计算
  7. SpringBoot - ApplicationRunner的作用是什么?
  8. 《数据结构课程实践》_01_学生成绩档案管理系统_实现
  9. 指针式仪表自动读数与识别(二):仪表图像预处理
  10. # 代码块 while