9

我正在尝试为服务发现实现consul,但我遇到了两件事:连接到自定义 DNS 服务器,以及格式化我的net.LookupSRV()请求。

这是我试图从我的 go 应用程序中查找的内容:

$ dig @127.0.0.1 -p 8600 serviceb.service.consul SRV

; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> @127.0.0.1 -p 8600 serviceb.service.consul SRV
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4511
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 2
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;serviceb.service.consul.   IN  SRV

;; ANSWER SECTION:
serviceb.service.consul. 0  IN  SRV 1 1 80 az1-serviceb1.node.dc1.consul.
serviceb.service.consul. 0  IN  SRV 1 1 80 az2-serviceb2.node.dc1.consul.

;; ADDITIONAL SECTION:
az1-serviceb1.node.dc1.consul. 0 IN A   10.6.41.22
az2-serviceb2.node.dc1.consul. 0 IN A   10.6.41.20

;; Query time: 6 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Fri May 16 15:09:28 2014
;; MSG SIZE  rcvd: 275

这是相关的代码。(我知道这是错误的,但只是为了让您可以看到我正在尝试做的事情)

cname, addrs, err := net.LookupSRV("serviceb", "service", "consul")
log.Printf("%+v %+v %+v", cname, addrs, err)

和输出:

2014/05/16 15:24:31  [] lookup _serviceb._service.consul: no such host

任何帮助,将不胜感激!谢谢

4

4 回答 4

4

尝试使用更锋利的工具,例如github.com/miekg/dns包装。上次我查看它时,它几乎可以控制客户端设置的每一点以进行 DNS 解析。

于 2014-05-16T16:21:00.177 回答
2

Consul 确实支持严格的 RFC 2782,并且只能使用标准库进行查找:

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(), "svcname", "tcp", "consul",
)
于 2020-03-13T14:06:36.753 回答
1

虽然这不能回答您的确切问题,但我发现它是访问新应用程序服务数据的一种更简单的方法。

调用 HTTP API 很容易net/http

package main
import (
    "fmt"
    "net/http"
    "io/ioutil"
)
func main() {
    resp, _ := http.Get("http://localhost:8500/v1/catalog/service/serviceb")
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Print(string(body))
}

服务指南中记录了 HTTP API 的基础知识。

于 2014-10-14T18:35:52.077 回答
1

最好的方法是使用 PreparedQueries,如Posted here

import (
    "fmt"

    consulapi "github.com/hashicorp/consul/api"
)

func main() {
    config := consulapi.DefaultConfig()
    consul, err := consulapi.NewClient(config)
    if err != nil {
        fmt.Println(err)
    }

preparedQuery := consul.PreparedQuery()
queryID, _, err := preparedQuery.Create(&consulapi.PreparedQueryDefinition{
    Name: "DnsQuery",
    Service: consulapi.ServiceQuery{
        Service:     "serviceb",
        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)
}
于 2020-06-27T06:26:28.633 回答