美文网首页
golang 注册和获取consul服务,api服务注册获取以及

golang 注册和获取consul服务,api服务注册获取以及

作者: 大地缸 | 来源:发表于2021-01-04 20:18 被阅读0次

    1.普通接口注册服务

    执行后就会出现下面那个服务,他这里会检查这个服务是否可用,不可用就会自动剔除

    package main
    
    import (
        "fmt"
        "net/http"
        consulapi "github.com/hashicorp/consul/api"
    )
    
    const (
        consulAddress = "124.70.156.31:8500"
        localIP       = "124.70.156.31"
        localPort     = 3001
    )
    
    func consulRegister() {
        // 创建连接consul服务配置
        config := consulapi.DefaultConfig()
        config.Address = consulAddress
        client, err := consulapi.NewClient(config)
        if err != nil {
            fmt.Println("consul client error : ", err)
        }
    
        // 创建注册到consul的服务到
        registration := new(consulapi.AgentServiceRegistration)
        registration.ID = "shitingbao"
        registration.Name = "service_shitingbao"//根据这个名称来找这个服务
        registration.Port = localPort
        registration.Tags = []string{"shitingbao_test_service"}//这个就是一个标签,可以根据这个来找这个服务,相当于V1.1这种
        registration.Address = localIP
    
        // 增加consul健康检查回调函数
        check := new(consulapi.AgentServiceCheck)
        check.HTTP = fmt.Sprintf("http://%s:%d", registration.Address, registration.Port)
        check.Timeout = "5s"                         //超时
        check.Interval = "5s"                        //健康检查频率
        check.DeregisterCriticalServiceAfter = "30s" // 故障检查失败30s后 consul自动将注册服务删除
        registration.Check = check
    
        // 注册服务到consul
        err = client.Agent().ServiceRegister(registration)
    }
    
    //Handler 3001
    func Handler(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("you are visiting health check api:3001"))
    }
    
    //ServerLoad 启动
    func ServerLoad() {
        consulRegister()
        //定义一个http接口
        http.HandleFunc("/", Handler)
        err := http.ListenAndServe(":3001", nil)
        if err != nil {
            fmt.Println("error: ", err.Error())
        }
    }
    
    

    2.grpc注册入consul

    grpc需要多做一步,因为consul需要一个健康检查,在api中验证是否可用是可以直接检查就行了,但是对于rpc的这种协议不一样处理,这里需要写一个自定义的检查函数,给consul检查。这个函数需要实现consul包中的RegisterHealthServer接口,grpc服务的代码就不展示了,这里展示了注册grpc的过程

    package main
    
    import (
        "context"
        "fmt"
        "log"
        "net"
        stb_server "stb_consul/external_service/stb_server"
        "stb_consul/external_service/stbserver"
    
        "github.com/hashicorp/consul/api"
        "github.com/sirupsen/logrus"
        "google.golang.org/grpc"
        "google.golang.org/grpc/health/grpc_health_v1"
    )
    
    // HealthImpl 健康检查实现
    type HealthImpl struct{}
    
    // Check 实现健康检查接口,这里直接返回健康状态,这里也可以有更复杂的健康检查策略,比如根据服务器负载来返回
    func (h *HealthImpl) Check(ctx context.Context, req *grpc_health_v1.HealthCheckRequest) (*grpc_health_v1.HealthCheckResponse, error) {
        return &grpc_health_v1.HealthCheckResponse{
            Status: grpc_health_v1.HealthCheckResponse_SERVING,
        }, nil
    }
    
    //Watch 这个没用,只是为了让HealthImpl实现RegisterHealthServer内部的interface接口
    func (h *HealthImpl) Watch(req *grpc_health_v1.HealthCheckRequest, w grpc_health_v1.Health_WatchServer) error {
        return nil
    }
    
    //grpc开启
    func externalServer() {
        lis, err := net.Listen("tcp", ":3001")
        if err != nil {
            logrus.Info("外置服务开启失败:", err)
            panic(err)
        }
        logrus.WithFields(logrus.Fields{
            "tcp": ":3001",
        }).Info("external server")
        s := grpc.NewServer()
        stbserver.RegisterStbServerServer(s, &stb_server.StbServe{})
        grpc_health_v1.RegisterHealthServer(s, &HealthImpl{})//比普通的grpc开启多了这一步
        s.Serve(lis)
        log.Println("grpc start")
    }
    
    //grpc注册进consul
    func grpcRegister() {
        config := api.DefaultConfig()
        config.Address = consulAddress
        client, err := api.NewClient(config)
        if err != nil {
            panic(err)
        }
        agent := client.Agent()
    
        reg := &api.AgentServiceRegistration{
            ID:      fmt.Sprintf("%v-%v-%v", "StbServe", localIP, localPort), // 服务节点的名称
            Name:    fmt.Sprintf("grpc.health.v1.%v", "StbServe"),            // 服务名称
            Tags:    []string{"StbServe"},                                    // tag,可以为空
            Port:    localPort,                                               // 服务端口
            Address: localIP,                                                 // 服务 IP
            Check: &api.AgentServiceCheck{ // 健康检查
                Interval: "5s", // 健康检查间隔
                // grpc 支持,执行健康检查的地址,service 会传到 Health.Check 函数中
                GRPC:                           fmt.Sprintf("%v:%v/%v", localIP, localPort, "StbServe"),
                DeregisterCriticalServiceAfter: "5s", // 注销时间,相当于过期时间
            },
        }
    
        if err := agent.ServiceRegister(reg); err != nil {
            panic(err)
        }
    }
    
    func grpcLoad() {
        grpcRegister()
        externalServer()
    }
    
    

    3.服务查看

    你可以在你的consul的UI中看见这个服务

    image image

    4.发现服务

    发现服务中的代码都是一样的,如下

    package main
    
    import (
        "fmt"
    
        "github.com/hashicorp/consul/api"
        "github.com/sirupsen/logrus"
    )
    
    func client() {
        var lastIndex uint64
        config := api.DefaultConfig()
        config.Address = "124.70.156.31:8500" //consul server
    
        client, err := api.NewClient(config)
        if err != nil {
            fmt.Println("api new client is failed, err:", err)
            return
        }
        services, metainfo, err := client.Health().Service("service_shitingbao", "shitingbao_test_service", true, &api.QueryOptions{
            WaitIndex: lastIndex, // 同步点,这个调用将一直阻塞,直到有新的更新
        })
        if err != nil {
            logrus.Panic("error retrieving instances from Consul:", err)
        }
        lastIndex = metainfo.LastIndex
    
        for _, service := range services {
            fmt.Println("service.Service.Address:", service.Service.Address, "service.Service.Port:", service.Service.Port)
        }
    }
    
    

    这里会输出ServiceName为‘service_shitingbao’,tag标签为shitingbao_test_service的服务,这个service_shitingbao就是上面红框里面的那个服务名称,对应的tag标签要对应上,没有就是空,不然获取不到

    相关文章

      网友评论

          本文标题:golang 注册和获取consul服务,api服务注册获取以及

          本文链接:https://www.haomeiwen.com/subject/isfboktx.html