今天主要讲的是 NSQD 中 Lookupd, NSQD通过Lookupd实现分布式集群。从前几篇的源码分析中可知 NSQD 与 Lookupd 的协作方式有以下几点:
1.NSQD启动时,会通过 TCP 上报它自己的身份信息给所有的Lookupd服务。
2.在 NSQD 创建新的Topic的时候,回去拉取 Lookupd 服务中,有关这个 Topic 的信息并初始化当前 Topic。
3.当 NSQD 有 Topic 或者 Channel 变动时(删除,新增等),上报 Lookupd 集群。
4.保持 NSQD 与 Lookupd 集群的心跳。
Lookupd 的主要作用在于管理 NSQD 集群服务中所有的 NSQD 的信息及相关 Topic 和 Channel。同时定时检查 NSQD 的在线情况。并提供 http 服务,以便查找 NSQD 集群的相关信息(topic, channel,消息总数等等)。
主要代码文件:
1.nsqlookupd/option.go lookupd配置信息
type Options struct {
LogLevel lg.LogLevel `flag:"log-level"` //日志等级
LogPrefix string `flag:"log-prefix"` //日志前缀
Logger Logger //日志生成接口
TCPAddress string `flag:"tcp-address"` //lookupd tcp 地址
HTTPAddress string `flag:"http-address"` //lookupd http 地址
BroadcastAddress string `flag:"broadcast-address"` //lookupd 广播地址
//nsqd 不活跃的时间
//lookupd 根据nsqd心跳来更新对应updateTime
//如果当前时间-updateTime>InactiveProducerTimeout 则视为服务失去连接
InactiveProducerTimeout time.Duration `flag:"inactive-producer-timeout"`
//墓碑状态,暂时不咋用(在查询活跃NSQD时,墓碑状态为true,且状态开始时间<TombstoneLifetime
的NSQD 会被过滤)
TombstoneLifetime time.Duration `flag:"tombstone-lifetime"`
}
2.nsqlookupd/nsqlookupd.go
结构体
type NSQLookupd struct {
sync.RWMutex //全局锁
opts *Options //options.go
tcpListener net.Listener //tcp 监听者
httpListener net.Listener //http 监听者
tcpServer *tcpServer //tcp 服务
waitGroup util.WaitGroupWrapper
DB *RegistrationDB //lookupd 定义的数据库 registration_db.go
}
New() 函数 初始化 NSQLookupd
func New(opts *Options) (*NSQLookupd, error) {
var err error
if opts.Logger == nil { //日志接口初始化
opts.Logger = log.New(os.Stderr, opts.LogPrefix, log.Ldate|log.Ltime|log.Lmicroseconds)
}
l := &NSQLookupd{
opts: opts,
DB: NewRegistrationDB(),
}
//TCP/HTTP 监听者
l.tcpListener, err = net.Listen("tcp", opts.TCPAddress)
l.httpListener, err = net.Listen("tcp", opts.HTTPAddress)
return l, nil
}
Main 函数 用于启动nsqlookupd, 主要包括启动 TCP 和 HTTP 监听服务
func (l *NSQLookupd) Main() error {
ctx := &Context{l}
exitCh := make(chan error)
var once sync.Once
exitFunc := func(err error) {
once.Do(func() {
if err != nil {
l.logf(LOG_FATAL, "%s", err)
}
exitCh <- err
})
}
l.tcpServer = &tcpServer{ctx: ctx}
l.waitGroup.Wrap(func() { //启动TCP
exitFunc(protocol.TCPServer(l.tcpListener, l.tcpServer, l.logf))
})
httpServer := newHTTPServer(ctx)
l.waitGroup.Wrap(func() { //启动HTTP
exitFunc(http_api.Serve(l.httpListener, httpServer, "HTTP", l.logf))
})
err := <-exitCh
return err
}
总结:Lookupd 的主要作用在于管理 NSQD 集群服务中 NSQD 的状态。Lookupd 主要包括两个服务(TCP/HTTP 服务),TCP 服务用于 NSQD 注册或注销 NSQD 信息,HTTP 服务用于其他客户端获取集群信息。
下一次分享:Loookupd DB数据结构的定义