Go Micro 使用 etcd 服务注册和发现

在构建微服务时,使用服务注册和发现可以减少配置的复杂性。

注册机制提供了一个服务发现机制来将名称解析为地址。它可以由consul,etcd,zookeeper,dns,gossip等提供支持。一个服务应该在启动时使用注册机制进行注册,并在关闭时取消注册。

Go Micro 支持 etcd、consul、mdns 多种方式进行服务注册和发现,默认使用 mdns。

etcd 是一个分布式一致性的 key-value 存储技术, 被用来做配置共享和服务发现。有关 etcd 的知识可以参照 etcd教程

 

1. 运行 etcd

etcd 在开发或者测试环境中,可以直接使用 docker 运行。

docker run --name etcd -d -p 2379:2379 -p 2380:2380 -e ALLOW_NONE_AUTHENTICATION=yes bitnami/etcd:3.3.11 etcd 

可以进入docker,执行客户端命令。

docker exec -it etcd /bin/bash

进入后可以直接执行 etcdctl 命令,默认是 V2 版本。如果使用 V3 版本,需要先执行如下命令:

export ETCDCTL_API=3

查看所有键值:

etcdctl get  / --prefix 

 

2. Go Micro 服务注册

Go Micro 的 RPC 微服务,使用 etcd 作为服务注册的方法如下:

package main
import (
        "github.com/micro/go-micro/util/log"
        "github.com/micro/go-micro"
        "hello/handler"
        "hello/subscriber"
        "github.com/micro/go-micro/registry"
        "github.com/micro/go-micro/registry/etcd"
        hello "hello/proto/hello"
)

func main() {
    // 创建 etcd 服务注册项,其中 192.168.3.25:2379 为 etcd 服务地址。
    // etcd 服务地址按照实际情况填写
    reg := etcd.NewRegistry(registry.Addrs("192.168.3.25:2379"))

    // 创建一个新的服务,服务名为 go.micro.srv.hello
    service := micro.NewService(
            micro.Name("go.micro.srv.hello"),
            micro.Version("latest"),
            // 使用服务注册插件
            micro.Registry(reg),
    )

    // 创建一个新的服务,服务名为 go.micro.srv.hello
    service := micro.NewService(
            micro.Name("go.micro.srv.hello"),
            micro.Version("latest"),
            // 使用服务注册插件
            micro.Registry(reg), 
    )

    // 通过命令行参数或者插件初始化服务
    service.Init()

    // 注册业务处理组件 handler.Hello
    hello.RegisterHelloHandler(service.Server(), new(handler.Hello))

    // 暂且忽略,可直接去掉
    //micro.RegisterSubscriber("go.micro.srv.hello", service.Server(), new(subscriber.Hello))

    // 暂且忽略,可直接去掉
    micro.RegisterSubscriber("go.micro.srv.hello", service.Server(), subscriber.Handler)

    // 运行服务
    if err := service.Run(); err != nil {
            log.Fatal(err)
    }
}

 

3. Go Micro 服务发现

Go Micro 客户端,可以通过服务发现使用注册在 etcd 的 RPC 微服务:

package main
import (
    "context"
    "github.com/micro/go-micro"
    "github.com/micro/go-micro/registry"
    "github.com/micro/go-micro/registry/etcd"
    "github.com/micro/go-micro/util/log"
    "hello/proto/hello"
)

func main() {
    // 创建 etcd 服务注册项,其中 192.168.3.25:2379 为 etcd 服务地址。
    // etcd 服务地址按照实际情况填写
    reg := etcd.NewRegistry(registry.Addrs("192.168.3.25:2379"))

    // Create a new service
    // 创建一个新的服务,服务名为 go.micro.srv.hello
    service := micro.NewService()

    // Parse command line flags
    // 使用服务注册插件初始化服务
    service.Init(micro.Registry(reg))

    // Use the generated client stub
    // 通过客户端的桩创建 go.micro.srv.hello 服务客户端
    helloService := hello.NewHelloService("go.micro.srv.hello",service.Client())

    // Make request
    // 调用 RPC Call 方法
    response, err := helloService.Call(context.Background(), &hello.Request{
        Name: "codebaoku",
    })
    if err != nil {
        log.Error(err)
        return
    }

    // Print result
    // 打印 RPC Call 调用结果
    log.Info(response.Msg)
}

测试代码如下package mainimport ("fmt""log""time""go.etcd.io/etcd/clientv3""golang.org/x/net/context")var ( ...