Consul 按照教程搭建集群后,无法获取已注册的服务
题目描述
按照 Deployment Guide 搭建了3个 Server 节点的集群,然后添加了2个 Client 节点,在任意节点注册一个服务后,尝试从其他节点获取,获取不到,但是在 UI 界面可以看到. 集群日志没有发现异常信息,设置完全是按照教程进行的,至少没有查出来差异.. 提前感谢..
相关代码
服务代码
package mainimport (
"context"
"fmt"
"log"
"net"
"net/http"
"os"
"os/signal"
"strings"
"syscall"
"time"
"github.com/gin-gonic/gin"
consulapi "github.com/hashicorp/consul/api"
)
const (
serviceName string = "111"
port int = 8003
)
var (
consulEndpoint string = "0.0.0.0:8500"
)
/*
服务主体
Graceful shutdown
启动时服务注册
终止时解注册
*/
func main() {
router := gin.Default()
router.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "ok")
})
srv := &http.Server{
Addr: fmt.Sprintf(":%d", port),
Handler: router,
}
register()
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
quit := make(chan os.Signal)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
deregister()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}
select {
case <-ctx.Done():
log.Println("timeout of 5 seconds")
}
log.Println("Server exiting")
}
/*
获取本机IP地址
*/
func getLocalIP() (string, error) {
conn, err := net.Dial("udp", "8.8.8.8:53")
if err != nil {
return "", err
}
addr := conn.LocalAddr().(*net.UDPAddr)
host := strings.Split(addr.String(), ":")[0]
return host, nil
}
/*
服务注册
*/
func register() {
// init client
config := consulapi.DefaultConfig()
config.Address = consulEndpoint
client, err := consulapi.NewClient(config)
if err != nil {
log.Fatalf("Service Register Failed: %s\n", err.Error())
}
host, err := getLocalIP()
if err != nil {
log.Fatalf("Service Register Failed: %s\n", err.Error())
}
// define registry
reg := &consulapi.AgentServiceRegistration{
ID: serviceName,
Name: serviceName,
Port: port,
Tags: []string{"test"},
Address: host,
Check: &consulapi.AgentServiceCheck{
TCP: fmt.Sprintf("%s:%d", host, port),
Timeout: "5s",
Interval: "10s",
Status: "passing",
DeregisterCriticalServiceAfter: "30s",
},
}
err = client.Agent().ServiceRegister(reg)
if err != nil {
log.Fatal(err.Error())
}
log.Println("Service Registered")
}
/*
服务解注册
*/
func deregister() {
config := consulapi.DefaultConfig()
config.Address = consulEndpoint
client, err := consulapi.NewClient(config)
if err != nil {
log.Fatal(err)
}
client.Agent().ServiceDeregister(serviceName)
log.Println("Service Deregistered")
}
调用代码
只能在注册服务的节点查到服务,其他节点拿不到任何一个服务的信息
package mainimport (
"net"
"fmt"
"log"
"strings"
consulapi "github.com/hashicorp/consul/api"
)
const (
serviceName string = "111"
)
var (
consulEndpoint string
)
func main() {
host, err := getLocalIP()
if err != nil {
log.Fatal(err)
}
consulEndpoint = fmt.Sprintf("%s:8500", host)
config := consulapi.DefaultConfig()
config.Address = consulEndpoint
client, err := consulapi.NewClient(config)
if err != nil {
log.Fatal(err)
}
services, _ := client.Agent().Services()
if len(services) == 0 {
log.Fatal("No Services")
}
for k, v := range services {
fmt.Println(k)
fmt.Printf("%#v", v)
}
service, qm, err := client.Agent().Service(serviceName, nil)
if err != nil {
log.Fatal("Get Service Failed:", err)
}
fmt.Printf("%#v\n", service)
fmt.Printf("%#v\n", qm)
}
func getLocalIP() (string, error) {
conn, err := net.Dial("udp", "8.8.8.8:53")
if err != nil {
return "", err
}
addr := conn.LocalAddr().(*net.UDPAddr)
host := strings.Split(addr.String(), ":")[0]
return host, nil
}
回答:
刚刚找到一个解决方案,自问自答一下..
client.Agent().Services()
获取的内容不完整,看起来只能获取本地 Agent 上注册的服务。如果要获取整个集群完整同步的信息,需要使用 client.Catalog().Services(nil)
。
集群的配置也不知道有没有问题,参考了网上很多人的代码,全都是使用的 Agent,但是我用就是没办法获取其他节点的服务信息。后面还要继续了解一下 Agent 的 Gossip Protocol。
另外就是查看文档之后才了解到 Catalog 这一层。 Catalog HTTP API 和 Agent HTTP API 这块儿还要再了解一下。
就算解决了一半吧,希望对其他遇到这个问题的人有帮助,也希望有大佬或者前辈能给出更准确的解答。
再来补充两个参考:
Consul difference between agent and catalog
Anti-Entropy
以上是 Consul 按照教程搭建集群后,无法获取已注册的服务 的全部内容, 来源链接: utcz.com/p/183819.html