NSQ系列(三):nsqlookupd原理和實現

nsqlookupd的角色類似於註冊中心,管理着nsqd -> Topic -> Channel的拓撲信息,提供Client查詢Topic和Channel的信息。nsqlookupd主要提供兩種接口:TCP接口,用於nsqd廣播信息;另外就是HTTP接口,讓Client可以服務發現或者admin可以進行管理操作。
啓動方式和nsqd類似,

func (p *program) Start() error {
	// 配置讀取
	...
	p.nsqlookupd = nsqlookupd

	go func() {
		err := p.nsqlookupd.Main()
		if err != nil {
			p.Stop()
			os.Exit(1)
		}
	}()

	return nil
}

啓動NSQLookupd實例,

func (l *NSQLookupd) Main() error {
	...
	tcpServer := &tcpServer{ctx: ctx}
	l.waitGroup.Wrap(func() {
		exitFunc(protocol.TCPServer(l.tcpListener, tcpServer, l.logf))
	})
	httpServer := newHTTPServer(ctx)
	l.waitGroup.Wrap(func() {
		exitFunc(http_api.Serve(l.httpListener, httpServer, "HTTP", l.logf))
	})

	err := <-exitCh
	return err
}

啓動一個TCP Server和一個HTTP Server,NSQDLoop協議實現代碼如下,

func (p *LookupProtocolV1) Exec(client *ClientV1, reader *bufio.Reader, params []string) ([]byte, error) {
	switch params[0] {
	case "PING":
		return p.PING(client, params)
	case "IDENTIFY":
		return p.IDENTIFY(client, reader, params[1:])
	case "REGISTER":
		return p.REGISTER(client, reader, params[1:])
	case "UNREGISTER":
		return p.UNREGISTER(client, reader, params[1:])
	}
	return nil, protocol.NewFatalClientErr(nil, "E_INVALID", fmt.Sprintf("invalid command %s", params[0]))
}

這部分的實現沒有太多很繞的邏輯,讀者如果自己感興趣,可以自己嘗試去閱讀下相關代碼。如果存在問題,歡迎留言交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章