在 go 中使用 consul 可以注册,但是健康检查一直不生效

来源:26-7 go集成consul

PARADISELIN

2023-06-27

在 server 代码中无论是使用 sdk 提供的注册方式注册,还是使用 api 的形式注册,都会显示健康查查失败,但是实际上服务是可用的,不知道是不是注册姿势有问题。

图片描述

以下是 server 部分的代码,注释掉那部分是使用 sdk 进行注册的代码

// server/main.go
package main

import (
	"context"
	"fmt"
	"log"
	"net"
	"sync"

	"github.com/hashicorp/consul/api"
	"github.com/imroc/req/v3"
	"google.golang.org/grpc"

	pb "grpc-resolver/proto"
)

var (
	consulAddress = "192.168.56.102:8500"
	serverHost    = "192.168.56.1"
	ports         = []int{50051, 50052}
)

type echoServer struct {
	pb.UnimplementedEchoServer
	addr string
}

func (s *echoServer) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) {
	return &pb.EchoResponse{Message: req.Message}, nil
}

// func registerServer(address string, port int, name string, tags []string, id string) error {
// 	conf := api.DefaultConfig()
// 	conf.Address = consulAddress

// 	client, err := api.NewClient(conf)
// 	if err != nil {
// 		log.Fatalf("failed to create consul client: %v", err)
// 	}

// 	check := &api.AgentServiceCheck{
// 		GRPC:                           fmt.Sprintf("%s:%d", address, port),
// 		GRPCUseTLS:                     false,
// 		Timeout:                        "5s",
// 		Interval:                       "5s",
// 		DeregisterCriticalServiceAfter: "10s",
// 	}

// 	registration := new(api.AgentServiceRegistration)
// 	registration.ID = id
// 	registration.Name = name
// 	registration.Port = port
// 	registration.Address = address
// 	registration.Tags = tags
// 	registration.Check = check

// 	err = client.Agent().ServiceRegister(registration)
// 	if err != nil {
// 		log.Fatalf("failed to register service: %v", err)
// 	}
// 	return nil
// }

func registerServer(address string, port int, name string, tags []string, id string) bool {
	client := req.C()
	res, err := client.R().SetBody(&api.AgentServiceRegistration{
		Name:    name,
		ID:      id,
		Tags:    tags,
		Address: address,
		Port:    port,
		Check: &api.AgentServiceCheck{
			Name:                           name,
			GRPC:                           fmt.Sprintf("%s:%d", address, port),
			GRPCUseTLS:                     false,
			Timeout:                        "5s",
			Interval:                       "5s",
			DeregisterCriticalServiceAfter: "15s",
		},
	}).Put(fmt.Sprintf("http://%s/v1/agent/service/register", consulAddress))

	if err != nil {
		log.Printf("register error: %v", err)
		return false
	}

	return res.StatusCode == 200
}

func startServer(port int) {
	addr := fmt.Sprintf("%s:%d", serverHost, port)
	lis, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}

	s := grpc.NewServer()
	pb.RegisterEchoServer(s, &echoServer{addr: addr})
	log.Printf("servering on %s\n", addr)

	_ = registerServer(serverHost, port, "echo", []string{"grpc", "echo"}, fmt.Sprintf("echo-%d", port))

	if err := s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}

}

func main() {
	var wg sync.WaitGroup
	for _, port := range ports {
		wg.Add(1)
		go func(port int) {
			defer wg.Done()
			startServer(port)
		}(port)
	}
	wg.Wait()
}

以下是 pb 文件,如果需要的话

syntax = "proto3";
option go_package = ".;proto";

// EchoRequest is the request for echo.
message EchoRequest {
  string message = 1;
}

// EchoResponse is the response for echo.
message EchoResponse {
  string message = 1;
}

// Echo is the echo service.
service Echo {
  rpc UnaryEcho(EchoRequest) returns (EchoResponse) {}
}

但是在课程中 python 服务用同样方式注册就没有问题,应该能排除 Windows 防火墙的问题。。。

图片描述

写回答

1回答

bobby

2023-06-29

你可以进入你的consul所在的容器中ping一下你的服务所在的ip地址,或者你注册的服务检测的ip地址是127.0.0.1,应该是外部可以访问的ip,或者你的服务中没有 /health路由?

0
1
PARADISELIN
我去。。。写的demo中没有注册 gRPC 健康检查服务。。。 感谢老师提醒!!!
2023-06-29
共1条回复

Go+Python打造电商系统 自研微服务框架 抓紧高薪机遇

快速转型Go工程师,成为具备双语言后端能力的开发者

515 学习 · 533 问题

查看课程