go 进阶 go-zero相关: 四. 服务注册原理

本文详细介绍了Go-zero框架中的zRPC服务注册与发现机制,包括服务注册的基础知识,如zRPC的模块组成,服务端如何启动并注册服务到etcd,以及服务注册的核心函数registerEtcd的创建和执行流程。此外,还探讨了服务注册后的续约监听过程,涉及到Publisher结构体和KeepAlive方法的工作原理。

一. 基础

  1. go-zero是一个集成了Web和RPC协议的服务框架,RPC也就是指go-zero的zRPC部分, zRPC底层依赖gRPC,内置了服务注册、负载均衡、拦截器等模块,其中还包括自适应降载,自适应熔断,限流等微服务治理方案,是一个简单易用的可直接用于生产的企业级RPC框架,我们在这里先了解一个服务治理这部分,怎么实现服务注册, 服务发现,服务更新的
  2. zRPC支持直连和基于etcd服务发现两种方式,
  3. zRPC中可以分成一下几个模块
  1. client: zRPC客户端,负责发起请求
  2. server: zRPC服务端,负责处理请求
  3. resolver: 服务注册模块,实现了gRPC的resolver.Builder接口并注册到gRPC
  4. discov: 服务发现模块,基于etcd实现服务发现功能
  5. balancer: 负载均衡模块,实现了p2c负载均衡算法,并注册到gRPC
  6. interceptor: 拦截器,对请求和响应进行拦截处理
  1. 在我们编写zrpc服务时,通常一个zrpc服务端,对应一个zrpc客户端, 在配置文件中设置etcd地址,将服务注册到etcd上,配置文件如下, 当服务端启动时会连接etcd将当前服务的服务名,服务地址保存到etcd, 当客户端启动时也会注册,同时会获取需要的服务端调用地址列表保存到本地
Name: hello.rpc           // 服务名
ListenOn: 127.0.0.1:9090  // 服务监听地址
Etcd:
  Hosts:
    - 127.0.0.1:2379      // etcd服务地址
  Key: hello.rpc          // 服务注册key
  1. 当客户端发起调用时会基于服务发现模块获取目标服务地址列表,负载均衡选择指定地址进行调用,并且基于拦截器统计请求结果,实现熔断限流等功能
  2. 接下来我们看一下服务注册,发现的源码,了解一下具体的执行流程

二. resolver 服务注册底层原理

  1. 参考博客
  2. 首先go-zero中rpc服务发现支持三种模式,当前只讨论服务发现模式
//直连模式
DirectScheme = "direct"
//服务发现模式
DiscovScheme = "discov"
//k8s模式
KubernetesScheme = "k8s"
  1. 编写rpc服务端时,需要配置etcd地址,设置当前服务名,服务启动时将当前服务调用地址保存到etcd,在上方已经做了配置文件的示例, 接下来看一下启动zrpc服务端代码
  1. 首先会读取配置文件,获取到当前服务的配置信息与etcd连接配置,
  2. 创建服务运行需要的Context对象,
  3. 通过proto生成的RegisterXXXServer(),将当前rpc服务实例注册到rpc服务器,
  4. 执行zrpc.MustNewServer()创建RpcServer,
  5. 调用RpcServer下的Start()启动服务
import (
	"flag"
	"fmt"
	"go_cloud_demo/rpc/internal/config"
	"go_cloud_demo/rpc/internal/server"
	"go_cloud_demo/rpc/internal/svc"
	"go_cloud_demo/rpc/types/user"
	"github.com/zeromicro/go-zero/core/conf"
	"github.com/zeromicro/go-zero/core/service"
	"github.com/zeromicro/go-zero/zrpc"
	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"
)

// 命令行参数读取配置文件所在路径
var configFile = flag.String("f", "rpc/etc/user.yaml", "the config file")

func main() {
   
   
	flag.Parse()
	//1.读取配置文件解析到Config结构体上
	var c config.Config
	conf.MustLoad(*configFile, &c)
	//2.创房服务运行上下文
	ctx := svc.NewServiceContext(c)

	//3.将服务注册到rpc服务器,并且监听指定端口启动服务
	//参数一"c.RpcServerConf":保存了当前rpc服务配置信息
	//参数二"func(grpcServer *grpc.Server)"一个函数,当执行该函数时
	//会调用通过proto生成的RegisterXXXServer(),将当前rpc服务实例注册到rpc服务器
	s := zrpc.MustNewServer(c.RpcServerConf,
		func(grpcServer *grpc.Server) {
   
   
			user.RegisterUserServer(grpcServer, server.NewUserServer(ctx))

			if c.Mode == service.DevMode || c.Mode == service.TestMode {
   
   
				reflection.Register(grpcServer)
			}
		})
	defer s.Stop()

	fmt.Printf("Starting rpc server at %s...\n", c.ListenOn)
	//4.启动
	s.Start()
}
  1. 了解服务注册中的可以分为两个步骤,分别是
  1. 执行MustNewServer()创建rpcServer时内部创建registerEtcd函数,并将该函数封装到keepAliveServer结构体中
  2. 执行Start()启动服务时,内部获取到keepAliveServer中保存的registerEtcd函数并执行,实现服务注册

1. 创建registerEtcd函数,并将该函数封装到keepAliveServer结构体中

  1. 我们看一下zrpc.MustNewServer()创建rpcServer源码,在"zrpc/server.go"下, 在MustNewServer()中调用了NewServer()
func MustNewServer(c RpcServerConf, register internal.RegisterFn) *RpcServer {
   
   
	//调用NewServer()
	server, err := NewServer(c, register)
	if err != nil {
   
   
		log.Fatal(err)
	}
	return server
}

// NewServer returns a RpcServer.
func NewServer(c RpcServerConf, register internal.RegisterFn) (*RpcServer, error) {
   
   
	var err error
	if err = c.Validate(); err != nil {
   
   
		return nil, err
	}

	var server internal.Server
	metrics := stat.NewMetrics(c.ListenOn)
	serverOptions := []internal.ServerOption{
   
   
		internal.WithMetrics(metrics),
		internal.WithRpcHealth(c.Health),
	}
	//判断是否配置了etcd连接地址与当前服务名key,如果有
	if c.HasEtcd() {
   
   
		//执行NewRpcPubServer()
		server, err = internal.NewRpcPubServer(c.Etcd, c.ListenOn, serverOptions...)
		if err != nil {
   
   
			return nil, err
		}
	} else {
   
   
		server = internal.NewRpcServer(c.ListenOn, serverOptions...)
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值