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]))
}

这部分的实现没有太多很绕的逻辑,读者如果自己感兴趣,可以自己尝试去阅读下相关代码。如果存在问题,欢迎留言交流。

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