Eagle

注册与发现

注册与发现

服务注册与发现基本是微服务开发中不可或缺的组件,Eagle 框架也提供了支持。

支持的组件

  • etcd
  • consul
  • nacos

服务注册

在服务启动的时候,Eagle 会通过 eagle.WithRegistry() 将当前实例注册到注册中心里,需提前创建一个 Registry; 同理,在服务停掉的时候,会从注册中心里剔除调。

不同的组件,使用方式基本相同,具体如下。

etcd

// main.go
import (
  ...
  "github.com/go-eagle/eagle/pkg/client/etcdclient"
  "github.com/go-eagle/eagle/pkg/registry/etcd"
  ...
)

func newApp(cfg *eagle.Config, gs *grpc.Server) *eagle.App {
	return eagle.New(
		eagle.WithName(cfg.Name),
		eagle.WithVersion(cfg.Version),
		eagle.WithLogger(logger.GetLogger()),
		eagle.WithServer(gs),
		eagle.WithRegistry(getEtcdRegistry()),
	)
}

func getEtcdRegistry() registry.Registry {
	client, err := etcdclient.New()
	if err != nil {
		log.Fatal(err)
	}
	return etcd.New(client.Client)
}

consul

// main.go
import (
  ...
  "github.com/go-eagle/eagle/pkg/client/consulclient"
  "github.com/go-eagle/eagle/pkg/registry/consul"
  ...
)

func newApp(cfg *eagle.Config, gs *grpc.Server) *eagle.App {
	return eagle.New(
		eagle.WithName(cfg.Name),
		eagle.WithVersion(cfg.Version),
		eagle.WithLogger(logger.GetLogger()),
		eagle.WithServer(gs,),
		eagle.WithRegistry(getConsulRegistry()),
	)
}

func getConsulRegistry() registry.Registry {
	client, err := consulclient.New()
	if err != nil {
		panic(err)
	}
	return consul.New(client)
}

nacos

// main.go
import (
  ...
  "github.com/go-eagle/eagle/pkg/client/nacosclient"
  "github.com/go-eagle/eagle/pkg/registry/nacos"
  ...
)

func newApp(cfg *eagle.Config, gs *grpc.Server) *eagle.App {
	return eagle.New(
		eagle.WithName(cfg.Name),
		eagle.WithVersion(cfg.Version),
		eagle.WithLogger(logger.GetLogger()),
		eagle.WithServer(gs,),
		eagle.WithRegistry(getNacosRegistry()),
	)
}

func getNacosRegistry() registry.Registry {
	client, err := nacosclient.New()
	if err != nil {
		panic(err)
	}
	return nacos.New(client)
}

服务发现

服务发现的实现也有多种方式,假定需要连接的是用户服务,服务名serviceName是 user-svc, 举例如下:

直连模式

支持多个节点,多个用逗号分隔

直连模式就不会用到服务名了

  ...
  endpoint := "127.0.0.1:9090"
	conn, err := grpc.DialInsecure(
		ctx,
		grpc.WithEndpoint(endpoint),
	)
  ...

etcd

func main() {
  ...
  endpoint := "discovery:///user-svc"
	conn, err := grpc.DialInsecure(
		ctx,
		grpc.WithEndpoint(endpoint),
		grpc.WithDiscovery(getEtcdDiscovery()),
	)
  ...
}

func getEtcdDiscovery() registry.Discovery {
	// create a etcd register
	client, err := etcdclient.New()
	if err != nil {
		panic(err)
	}
	return etcd.New(client.Client)
}

consul

func main() {
  ...
  endpoint := "discovery:///user-svc"
	conn, err := grpc.DialInsecure(
		ctx,
		grpc.WithEndpoint(endpoint),
		grpc.WithDiscovery(getConsulDiscovery()),
	)
  ...
}

func getConsulDiscovery() registry.Discovery {
	client, err := consulclient.New()
	if err != nil {
		panic(err)
	}
	return consul.New(client)
}

nacos

这里需要注意,nacos和etcd,consul不同的是,endpoint 需要在服务名后面带上 .grpc 后缀,这和 nacos 注册时的处理有关。

func main() {
  ...
  endpoint := "discovery:///user-svc.grpc"
	conn, err := grpc.DialInsecure(
		ctx,
		grpc.WithEndpoint(endpoint),
		grpc.WithDiscovery(getNacosDiscovery()),
	)
  ...
}

func getNacosDiscovery() registry.Discovery {
	client, err := nacosclient.New()
	if err != nil {
		panic(err)
	}
	return nacos.New(client)
}

配置

不同组件的配置都集中到了一个文件里:config/registry.yaml, 具体参数如下

# config/registry.yaml
etcd:
  Endpoints:
    - "127.0.0.1:2379"
  ConnectTimeout: 5s
  BasicAuth:
  UserName:
  Password:
  Secure: false
  AutoSyncInterval: 1s
  TTL:
consul:
  Addr: "127.0.0.1:8500"
  Scheme: http
  Datacenter:
  WaitTime: 5s
nacos:
  Addr: "127.0.0.1"
  Port: 8848
  NamespaceId: public
  TimeoutMs: 5000
  LogDir:
  CacheDir: warn  # debug,info,warn,error, default is info

注意:consul的配置不能带有 Namespace 参数, 此功能只有企业版支持,如果强行开启会报如下错误 Unexpected response code: 400 (Bad request: Invalid query parameter: "ns" - Namespaces are a Consul Enterprise feature)

可以根据不同的场景进行配置。