我有一个Main应用程序和多个工作程序节点,它们在领事中注册。我想通过负载平衡将数据发送到工作节点。使用congo的golang API,我可以在主应用程序上获得可用的服务。
但是,我无法在golang应用程序中获取DNS SRV记录。
如该线程中所述,如何在go应用程序中读取领事SRV记录?,我尝试了github.com/miekg/dns,但没有成功。另外,我尝试使用github.com/benschw/consul- clb-go,如下所示:
c := clb.NewClb("127.0.0.1", "8600", clb.Random) srvRecord := "Processor" + ".service.consul" address, err := c.GetAddress(srvRecord) if err != nil { fmt.Println(err) } fmt.Println(address)
它给了我这个错误:
panic: runtime error: index out of range [0] with length 0
另外,我尝试使用net包,如下所示:
resolver := &net.Resolver{ Dial: func(ctx context.Context, network, address string) (net.Conn, error) { return (&net.Dialer{}).DialContext(ctx, network, "127.0.0.1:8600") }, } _, addrs, err := resolver.LookupSRV( context.Background(), "Processor", "tcp", "consul", ) if err != nil { fmt.Printf("Error : %v", err) } fmt.Println(addrs)
它返回:
Error : lookup _Processor._tcp.consul: dnsquery: DNS name does not exist.[]
我还尝试将“服务”添加到查询字符串,但它也返回了相同的错误。
但是,挖掘正确返回:
C:\Users\Sude>dig @127.0.0.1 -p 8600 Processor.service.consul SRV ; <<>> DiG 9.8.8 <<>> @127.0.0.1 -p 8600 Processor.service.consul SRV ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62807 ;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0 ;; WARNING: recursion requested but not available ;; QUESTION SECTION: ;Processor.service.consul. IN SRV ;; ANSWER SECTION: Processor.service.consul. 0 IN SRV 1 1 8001 localhost. Processor.service.consul. 0 IN SRV 1 1 8005 localhost. Processor.service.consul. 0 IN SRV 1 1 8004 localhost. ;; Query time: 0 msec ;; SERVER: 127.0.0.1#8600(127.0.0.1) ;; WHEN: Sat Jun 27 09:37:05 India Standard Time 2020 ;; MSG SIZE rcvd: 129
如何在go应用程序中读取这些记录?
此外,Go Consul API中是否有任何功能可以获取负载平衡的端点?这也将足够。
在查看Consul Golang API文档后,我找到了解决方案。最好的方法是使用PreparedQueries:
preparedQuery := consul.PreparedQuery() queryID, _, err := pq.Create(&consulapi.PreparedQueryDefinition{ Name: "DnsQuery", Service: consulapi.ServiceQuery{ Service: "Processor", OnlyPassing: true, }, }, &consulapi.WriteOptions{}) if err != nil { fmt.Println(err) } res, _, _ := preparedQuery.Execute(queryID, &consulapi.QueryOptions{}) for _, node := range res.Nodes { fmt.Println(node.Service.Address, node.Service.Port) }
res.Nodes是服务端点的一部分。