go-micro registry 服务的注册和发现

  go-micro的服务发现插件有mdns、consul、etcd等,默认使用mdns

  server、client的服务注册和发现的逻辑如下图:

 

  go-micro在客户端做的负载,典型的Balancing-aware Client模式。

  服务端把服务的地址信息保存到Registry, 然后定时的心跳检查,或者定时的重新注册服务。客户端监听Registry,最好是把服务信息保存到本地,监听服务的变动,更新缓存。当调用服务端的接口是时,根据客户端的服务列表和负载算法选择服务端进行通信。

   go-micro的Registry接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// The registry provides an interface for service discovery
// and an abstraction over varying implementations
// {consul, etcd, zookeeper, ...}
type Registry interface {
    Init(...Option) error
    Options() Options
    Register(*Service, ...RegisterOption) error
    Deregister(*Service) error
    GetService(string) ([]*Service, error)
    ListServices() ([]*Service, error)
    Watch(...WatchOption) (Watcher, error)
    String() string
}
 
// Watcher is an interface that returns updates
// about services within the registry.
type Watcher interface {
    // Next is a blocking call
    Next() (*Result, error)
    Stop()
}
 
// Result is returned by a call to Next on
// the watcher. Actions can be create, update, delete
type Result struct {
    Action  string
    Service *Service
}

  

go-micro 服务端注册服务

     

     服务端看上去流程还是比较简单的,当服务端调用Run()方法时,会调用service.Start()方法。这个除了监听端口,启动服务,还会把服务的ip端口号信息,和所有的公开接口的元数据信息保存到我们选择的Register服务器上去。

     看上去没有问题,但是,如果我们的节点发生故障,也是需要告诉Register把我们的节点信息删除掉。

     Run()方法中有个go s.run(ex) 方法的调用,这个方法就是根据我们设置interval去重新注册服务,当然比较保险的方式是我们把服务的ttl也设置上,这样当服务在未知的情况下崩溃,到了ttl的时间Register服务也会自动把信息删除掉。

 

    设置服务的ttl和 interval

复制代码
复制代码
    // 初始化服务
    service := micro.NewService(
        micro.Name(common.ServiceName),
        micro.RegisterTTL(time.Second*30),
        micro.RegisterInterval(time.Second*20),
        micro.Registry(reg),
    )
复制代码
复制代码

  ttl就是注册服务的过期时间,interval就是间隔多久再次注册服务。如果系统崩溃,过期时间也会把服务删除掉。客户端当然也会有相应的判断,下面会详细解说 

客户端发现服务

    客户端的服务发现要步骤多一些,但并不复杂,他涉及到服务选择Selector和服务发现Register两部分。

    Selector是基于服务发现的,根据你选择的主机选择算法,返回主机的信息。默认的情况,go-micro是每次要得到服务器主机的信息都要去Register去获取。但是查看cmd.go的源码你会发现默认初始化的值,selector的默认flag是cache。DefaultSelectors里的cache对应的就是初始化cacheSelector方法

 

    但是当你在执行service.Init()方法时

go-micro会把默认的selector替换成cacheSelector,具体的实现是在cmd.go的Before方法里

cacheSelector 会把从Register里获取的主机信息缓存起来。并设置超时时间,如果超时则重新获取。在获取主机信息的时候他会单独跑一个协程,去watch服务的注册,如果有新节点发现,则加到缓存中,如果有节点故障则删除缓存中的节点信息。当client还要根据selector选择的主机选择算法才能得到主机信息,目前只有两种算法,循环和随机法。为了增加执行效率,很client端也会设置缓存连接池,这个点,以后会详细说。

 所以大概的客户端服务发现流程是下面这样

     主要的调用过程都在Call方法内

 

主要的思路是

    从Selector里得到选择主机策略方法next。

    根据Retory是否重试调用服务,调用服务的过程是,从next 方法内得到主机,连接并传输数据 ,如果失败则重试,重试时,会根据主机选择策略方法next重新得到一个新的主机进行操作。

posted @   林锅  阅读(1692)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2016-04-18 Eclipse JDK的安装
2016-04-18 Lumen 配置、重写、404错误等
点击右上角即可分享
微信分享提示