今天主要講的是 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數據結構的定義