【go-zero框架】2.服务注册与发现


go-zero支持三种服务注册与发现方式:

  • 直连:指定目标地址endpoints
  • 基于etcd
  • 基于k8s:依赖k8s的集群管理机制,服务发现时直接去k8s的Endpoints里获

本篇讨论etcd的服务注册与发现方式~

1 server端的服务注册

1.1 用法

只需要在rpc的服务配置yaml文件中,定义etcd配置即可:

Rpc:
  Etcd:
     Hosts:
     - 192.168.0.111:2379
     - 192.168.0.112:2379
     - 192.168.0.113:2379
     Key: user.rpc
  • Host: etcd集群地址
  • Key: 服务标识,go-zero将以此key作为etcd注册key的前缀

使用配置启动服务,可以看到,go-zero已经帮我们把key注册到了etcd中了:

$ etcdctl --endpoints=121.0.0.1:2379 --prefix=true get user.rpc
user.rpc/7952388177561657362
localhost:9000
  • key:{服务标识}/{etcd租约id}
  • value:服务请求地址。

1.2 原理

go-zero在启动服务时的服务注册过程如下:

rpc服务入口初始化的调用链 zrpc.MustNewServer->zrpc.NewServer->internal.NewRpcPubServer

在internal.NewRpcPubServer中定义出了etcd服务注册的func registerEtcd, 代码:

func NewRpcPubServer(etcd discov.EtcdConf, listenOn string, middlewares ServerMiddlewaresConf, opts ...ServerOption) (Server, error) {
	registerEtcd := func() error {
		//...
		
		// etcd身份认证
		if etcd.HasAccount() {
			pubOpts = append(pubOpts, discov.WithPubEtcdAccount(etcd.User, etcd.Pass))
		}
		
		// tls认证
		if etcd.HasTLS() {
			pubOpts = append(pubOpts, discov.WithPubEtcdTLS(etcd.CertFile, etcd.CertKeyFile,
				etcd.CACertFile, etcd.InsecureSkipVerify))
		}
		
		// 是否指定了leaseId
		if etcd.HasID() {
			pubOpts = append(pubOpts, discov.WithId(etcd.ID))
		}
		
		// 将key写入etcd,并开启一个goroutine持续续租
		pubClient := discov.NewPublisher(etcd.Hosts, etcd.Key, pubListenOn, pubOpts...)
		return pubClient.KeepAlive()
	}
	server := keepAliveServer{
		registerEtcd: registerEtcd,
		Server:       NewRpcServer(listenOn, middlewares, opts...),
	}

	return server, nil
}

那么在服务启动时,通过调用链:s.Start->rs.server.Start->keepAliveServer.Start->registerEtcd

就实际调用了registerEtcd()方法,完成服务的注册。

2 client端的服务发现

2.1 用法

client端在与server端建立连接时,在代码中添加etcd配置即可:

func main() {
    conn := zrpc.MustNewClient(zrpc.RpcClientConf{
        Etcd: discov.EtcdConf{
            Hosts: []string{"127.0.0.1:2379"},
            Key:   "user.rpc",  // 服务标识,与服务端yaml中定义的保持一致
        },
    })
    client := greet.NewGreetClient(conn.Conn())
    resp, err := client.Ping(context.Background(), &greet.Request{})
    //...
}

这样客户端就可以直接通过etcd去发现目的服务了。

2.2 原理

go-zero在客户端连接时的服务发现过程如下:

初始化客户端NewClient的调用链:zrpc.MustNewClient->NewClient->internal.NewClient->cli.dial->grpc.DialContext->cc.idlenessMgr.ExitIdleMode->m.enforcer.ExitIdleMode->idler.ExitIdleMode->cc.resolverWrapper.start->ccr.cc.resolverBuilder.Build

最后调到的实际是go-zero中定义的discovBuilder.Build,它实现了grpc resolver的Build,完成实际的服务发现,即从etcd查找与监听服务注册的key的过程。

看一下discovBuilder.Build的实现:

type discovBuilder struct{}

func (b *discovBuilder) Build(target resolver.Target, cc resolver.ClientConn, _ resolver.BuildOptions) (resolver.Resolver, error) {
	//...
	
	// subscriber订阅etcd事件,监听key的变化
	sub, err := discov.NewSubscriber(hosts, targets.GetEndpoints(target))
	if err != nil {
		return nil, err
	}
    
    // 取出当前etcd中的值,也就是目标地址(多个),采用某种负载均衡策略选择一个进行连接
	update := func() {
		var addrs []resolver.Address
		// sub.Values中保存了实时的value, 有事件变化时会更新
		for _, val := range subset(sub.Values(), subsetSize) {
			addrs = append(addrs, resolver.Address{
				Addr: val,
			})
		}
		
		// 有变更时将地址更新给grpc
		if err := cc.UpdateState(resolver.State{
			Addresses: addrs,
		}); err != nil {
			logx.Error(err)
		}
	}
	sub.AddListener(update)
	update()

	return &nopResolver{cc: cc}, nil
}
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go-Micro 和 Go-Zero 都是 Go 语言领域中受欢迎的微服务框架,它们各自有不同的特点和适用场景。下面是它们的优缺点和受欢迎程度的概述: Go-Micro 框架的优点: 1. 社区活跃:Go-Micro 是一个开源项目,并且拥有活跃的社区支持,可以从社区中获取丰富的资源和支持。 2. 多语言支持:Go-Micro 提供了多语言支持,可以用于构建多语言之间的微服务应用。 3. 插件系统:Go-Micro 提供了插件系统,可以方便地扩展和定制功能。 4. 多种通信协议支持:Go-Micro 支持多种通信协议,包括 HTTP、gRPC、AMQP 等。 5. 高度可定制性:Go-Micro 提供了很高的可定制性,可以根据需求进行灵活配置和扩展。 Go-Micro 框架的缺点: 1. 上手难度较高:对于初学者来说,Go-Micro 的学习曲线可能相对陡峭,需要一些时间和经验来掌握和理解其概念。 2. 文档相对不完善:尽管有一些文档和示例可供参考,但相对来说,Go-Micro 的文档可能相对不够完善。 Go-Zero 框架的优点: 1. 简单易用:Go-Zero 的设计目标是简化开发流程和提高开发效率,提供了简洁易用的 API 和工具,使得开发者能够快速上手并构建稳定可靠的微服务应用。 2. 高性能:Go-Zero 采用了一系列优化策略,包括代码生成、缓存、连接池等,以提供高性能的微服务框架。 3. 内置功能丰富:Go-Zero 提供了许多内置功能,例如日志、配置、错误处理、中间件等,可以帮助开发者更快速地构建微服务应用。 4. 兼容性强:Go-Zero 支持多种传输协议和数据格式,包括 HTTP、gRPC、JSON 等,并且可以与其他框架和组件进行无缝集成。 Go-Zero 框架的缺点: 1. 相对较新:Go-Zero 是一个相对较新的框架,与一些其他框架相比,可能还没有得到广泛的应用和验证。 2. 社区相对较小:相对于一些其他流行的框架,Go-Zero 的社区规模可能相对较小,获取支持和资源可能相对有限。 关于哪个框架使用的人更多,这取决于具体的使用场景、个人偏好和团队需求。目前来说,Go-Micro 可能更受欢迎一些,因为它具有更长时间的发展历史和更大的社区规模。但是随着 Go-Zero 的不断发展和改进,它也在逐渐受到更多人的关注和使用。最终选择哪个框架,建议根据项目需求、团队经验和个人偏好进行评估和选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值