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 ( ...