• nsq源码阅读笔记之nsqd(一)——nsqd的配置解析和初始化


    配置解析

    nsqd的主函数位于apps/nsqd.go中的main函数

    首先main函数调用nsqFlagsetParse进行命令行参数集初始化, 
    然后判断version参数是否存在,若存在,则打印版本号并退出程序

    接下来钩住系统的syscall.SIGINTsyscall.SIGTERM消息,用来阻塞主goroutine防止退出

    随后判断config参数是否存在,若存在的话还需进行配置文件的读取, 
    nsq使用toml格式的配置文件,并通过github.com/BurntSushi/toml库进行配置文件的读取和解析

    如果配置文件存在并且符合toml格式,则调用cfg.Validate对配置文件的各项进行进一步的合法性检查。 
    主要是检查配置文件中有关tls的选项(是否支持以及支持的版本)

    配置文件检查通过后,创建默认配置opts,并于命令行参数和配置文件进行合并。 
    合并时用到了github.com/mreiferson/go-options库。 
    若出现冲突,则优先级从高到低排序依次是命令行、配置文件和默认配置 
    使用合并后的参数集初始化真正的nsqd对象

    最后,nsqd对象进行初始化和检查后,启动nsqd包的主函数,程序从跳转apps/nsqd.gonsqd/nsqd.go

    初始化

    nsqd真正开始运行前需要执行nsqd/nsqd.go中的LoadMetadataPersistMetadata两个函数

    LoadMetadata

    初始化nsqd的LoadMetadata函数使用atomic包中的方法来保证方法执行前和执行后isLoading值的改变

    元数据以json格式保存在nsqd可执行文件目录下的nsqd.%d.dat中。其中%d为代表该程序的ID, 
    通过在启动时的命令行worker-id或者配置文件中的id指定。默认ID是通过对主机名散列后获得。 
    因此保证了同一台机器每次启动的ID相同。

    解析元数据的文件得到系统中的存在的topic列表,遍历topic列表中的每个topic:

    1. 检查topic名称是否合法(长度在1-64之间,满足正则表达式^[.a-zA-Z0-9_-]+(#ephemeral)?$) 
      ,若不合法则忽略
    2. 使用GetTopic函数通过名字获得topic对象
    3. 判断当前topic对象是否处于暂停状态,是的话调用Pause函数暂停topic
    4. 获取当前topic下所有的channel,并且遍历channel,执行的操作与topic基本一致 
      1. 检查channel名称是否合法(长度在1-64之间,满足正则表达式^[.a-zA-Z0-9_-]+(#ephemeral)?$) 
        ,若不合法则忽略
      2. 使用GetChannel函数通过名字获得channel对象
      3. 判断当前channel对象是否处于暂停状态,是的话调用Pause函数暂停channel

    至此,元数据的载入完成

    PersistMetadata

    PersistMetadata将当前的topic和channel信息写入nsqd.%d.dat文件中, 
    主要步骤是忽略#ephemeral结尾的topic和channel后将topic和channel列表json序列化后写回文件中

    写入文件时先创建扩展名为tmp的临时文件,写入内容后并保存后再调用atomicRename函数将tmp文件重命名为nsqd.%d.dat。 
    其中atomicRename函数在windows和其他操作系统下实现方式不同,分别位于nsqd/rename_windows.go 
    rename.go中。在Linux下直接调用了os.Rename函数,而Windows下则使用Win32 API实现了文件的重命名。 
    这是因为go的早期版本中Windows下调用os.Rename函数时如果重命名后的文件已经存在则会失败。 
    这个bug在os: make Rename atomic on Windows中提到, 
    并且已经在os: windows Rename should overwrite destination file.提交中被修复, 
    因此,Golang1.5不存在这一bug

    Main

    Main函数中,nsqd真正开始运行。Main监听tcp,https(如果设置了相关参数),http端口并通过WaitGroupWrapperWrap函数以goroutine方式启动主要的组件。

    其中WaitGroupWrapper是对sync.WaitGroup的简单包装

    执行完Main函数后,配置和初始化工作全部完成,各个组件启动运行,而主goroutine会阻塞在<-signalChan处,直到收到中断程序的信号,随后执行nsqd.Exit函数。 
    Exit函数将进行socket关闭等清理工作,随后结束整个程序的运行。

  • 相关阅读:
    android基础开发之scrollview
    java网络---再论URL & URI
    Android Studio 有用的插件
    java网络---查找Internet
    java网络---流
    Qt学习之路(1)------Qt常用类用法说明
    将批量下载的博客导入到手机后,通过豆约翰博客阅读器APP(Android手机)进行浏览,白字黑底,保护眼睛,图文并茂。
    如何收藏互联网上的任意网页到系统某个分类下,之后进行批量导出发布等---博客备份专家的博文收藏功能您不可不知
    很喜欢看某方面的文章,如何将不同站点,不同博主同一类别的文章归类整合到一起,再批量导出成各种格式---豆约翰博客备份专家新增按分类收藏博文功能
    豆约翰博客备份专家博客导出示例(PDF,CHM)
  • 原文地址:https://www.cnblogs.com/zhangboyu/p/7457061.html
Copyright © 2020-2023  润新知