nsq源码阅读笔记之nsqd(一)——nsqd的配置解析和初始化
配置解析
nsqd的主函数位于apps/nsqd.go中的main函数
首先main函数调用nsqFlagset和Parse进行命令行参数集初始化,
然后判断version参数是否存在,若存在,则打印版本号并退出程序
接下来钩住系统的syscall.SIGINT和syscall.SIGTERM消息,用来阻塞主goroutine防止退出
随后判断config参数是否存在,若存在的话还需进行配置文件的读取,
nsq使用toml格式的配置文件,并通过github.com/BurntSushi/toml库进行配置文件的读取和解析
如果配置文件存在并且符合toml格式,则调用cfg.Validate对配置文件的各项进行进一步的合法性检查。
主要是检查配置文件中有关tls的选项(是否支持以及支持的版本)
配置文件检查通过后,创建默认配置opts,并于命令行参数和配置文件进行合并。
合并时用到了github.com/mreiferson/go-options库。
若出现冲突,则优先级从高到低排序依次是命令行、配置文件和默认配置
使用合并后的参数集初始化真正的nsqd对象
最后,nsqd对象进行初始化和检查后,启动nsqd包的主函数,程序从跳转apps/nsqd.go到nsqd/nsqd.go
初始化
nsqd真正开始运行前需要执行nsqd/nsqd.go中的LoadMetadata和PersistMetadata两个函数
LoadMetadata
初始化nsqd的LoadMetadata函数使用atomic包中的方法来保证方法执行前和执行后isLoading值的改变
元数据以json格式保存在nsqd可执行文件目录下的nsqd.%d.dat中。其中%d为代表该程序的ID,
通过在启动时的命令行worker-id或者配置文件中的id指定。默认ID是通过对主机名散列后获得。
因此保证了同一台机器每次启动的ID相同。
解析元数据的文件得到系统中的存在的topic列表,遍历topic列表中的每个topic:
- 检查topic名称是否合法(长度在1-64之间,满足正则表达式
^[\.a-zA-Z0-9_-]+(#ephemeral)?$)
,若不合法则忽略 - 使用
GetTopic函数通过名字获得topic对象 - 判断当前topic对象是否处于暂停状态,是的话调用
Pause函数暂停topic - 获取当前topic下所有的channel,并且遍历channel,执行的操作与topic基本一致
- 检查channel名称是否合法(长度在1-64之间,满足正则表达式
^[\.a-zA-Z0-9_-]+(#ephemeral)?$)
,若不合法则忽略 - 使用
GetChannel函数通过名字获得channel对象 - 判断当前channel对象是否处于暂停状态,是的话调用
Pause函数暂停channel
- 检查channel名称是否合法(长度在1-64之间,满足正则表达式
至此,元数据的载入完成
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端口并通过WaitGroupWrapper的Wrap函数以goroutine方式启动主要的组件。
其中WaitGroupWrapper是对sync.WaitGroup的简单包装
执行完Main函数后,配置和初始化工作全部完成,各个组件启动运行,而主goroutine会阻塞在<-signalChan处,直到收到中断程序的信号,随后执行nsqd.Exit函数。 Exit函数将进行socket关闭等清理工作,随后结束整个程序的运行。
nsq源码阅读笔记之nsqd(一)——nsqd的配置解析和初始化的更多相关文章
- nsq源码阅读笔记之nsqd(二)——Topic
与Topic相关的代码主要位于nsqd/nsqd.go, nsqd/topic.go中. Topic的获取 Topic通过GetTopic函数获取 GetTopic函数用于获取topic对象,首先先尝 ...
- nsq源码阅读笔记之nsqd(四)——Channel
与Channel相关的代码主要位于nsqd/channel.go, nsqd/nsqd.go中. Channel与Topic的关系 Channel是消费者订阅特定Topic的一种抽象.对于发往Topi ...
- nsq源码阅读笔记之nsqd(三)——diskQueue
diskQueue是backendQueue接口的一个实现.backendQueue的作用是在实现在内存go channel缓冲区满的情况下对消息的处理的对象. 除了diskQueue外还有dummy ...
- CI框架源码阅读笔记5 基准测试 BenchMark.php
上一篇博客(CI框架源码阅读笔记4 引导文件CodeIgniter.php)中,我们已经看到:CI中核心流程的核心功能都是由不同的组件来完成的.这些组件类似于一个一个单独的模块,不同的模块完成不同的功 ...
- CI框架源码阅读笔记4 引导文件CodeIgniter.php
到了这里,终于进入CI框架的核心了.既然是“引导”文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.c ...
- CI框架源码阅读笔记3 全局函数Common.php
从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap ...
- CI框架源码阅读笔记2 一切的入口 index.php
上一节(CI框架源码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程,这里再次贴出流程图,以备参考: 作为CI框架的入口文件,源码阅读,自然由此开始.在源码阅读的过程中, ...
- 源码阅读笔记 - 1 MSVC2015中的std::sort
大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格 ...
- Three.js源码阅读笔记-5
Core::Ray 该类用来表示空间中的“射线”,主要用来进行碰撞检测. THREE.Ray = function ( origin, direction ) { this.origin = ( or ...
随机推荐
- contentType,charset和pageEncoding的区别
简单点总结就是jsp页面头上这样写 <%@ page contentType="text/html;charset=GBK" %> 页面用GBK编码 pageEnco ...
- 发现DELL笔记本一个很弱智的问题
以前用联想的笔记本,最近联想笔记本坏了,用的是公司的DELL笔记本,发现DELL笔记本一个很弱智的问题. 关于禁用触摸板的问题. 起因: 由于要经常写程序,我配置的有有线鼠标,但是打字时经常碰到触摸板 ...
- Day7 类的继承和继承实现的原理
继承可以分为但继承,多继承. 继承的基本形式 class ParentClass1(object): #定义父类 pass class ParentClass2: #定义父类 pass class S ...
- Java面试与回答技巧(1.如何正确的面试)
在IT行业中,大部分公司很难用有效的方式招到合适的人.直接暴露出来的问题是:・花重金招了一个人,但实际的战斗力还比不上应届毕业生.・招聘了一个知名企业的高管,引入了一些高大上的技术,结果本来稳定的生产 ...
- mysql-列属性
列属性 列属性是真正约束字段的数据类型,但是数据类型的约束很单一,需要有一些额外的约束来确保数据的合法性 NULL/NOT NULL.default.primary key.unique key.au ...
- RabbitMQ Linux(Redhat6.5)安装(二 )
一.安装erlang 由于RabbitMq的linux运行环境需要erlang环境,所以需要先安装erlang: 1.erlang下载: http://erlang.org/download/(我下载 ...
- jenkins中集成commander应用
jenkins中集成commander应用 jenkins 集成测试 promotion 最近参加公司的集成测试平台的开发,在开发中遇到了不少问题,两个星期的迭代也即将完成,在这也用这篇博客记录下开发 ...
- js万年历,麻雀虽小五脏俱全,由原生js编写
对于前端来说,我们可能见到最多的就是各种各样的框架,各种各样的插件了,有各种各样的功能,比如轮播啊,日历啊,给我们提供了很大的方便,但是呢?我们在用别人这些写好的插件,框架的时候,有没有试着问一问自己 ...
- Python《学习手册:第二章-习题》
什么是Python解释器? Python解释器是运行Python程序的程序. 什么是源代码? 源代码是为程序所写的语句:它包括文本文件(通常以.py为文件名结尾)的文件. 什么是字节码? 字节码是Py ...
- 网络营销行业十大看了就想吐的“滥词”
网络营销行业在国内的互联网界已"猖獗"数年之久,它是一个让企业爱让用户恨的行业.有互联网的地方,就有网络营销的机会,有了机会就有了相关产业的存在,只不过是业大业小的问题.但是随着互 ...