跳到主要内容

注册与发现

服务注册与发现基本是微服务开发中不可或缺的组件,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)

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