前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自己动手实现 Go 的服务注册与发现(下)

自己动手实现 Go 的服务注册与发现(下)

作者头像
aoho求索
发布2021-12-27 10:41:12
1.1K0
发布2021-12-27 10:41:12
举报
文章被收录于专栏:aoho求索

你好,我是aoho,今天我们继续来介绍自己动手实现 Go 的服务注册与发现(结束)。

通过服务发现与注册中心,可以很方便地管理系统中动态变化的服务实例信息。与此同时,它也可能成为系统的瓶颈和故障点。因为服务之间的调用信息来自于服务注册与发现中心,当它不可用时,服务之间的调用可能无法正常进行。因此服务发现与注册中心一般会多实例部署,提供高可用性和高稳定性。

我们将基于 Consul 实现 Golang Web 的服务注册与发现。首先我们会通过原生态的方式,直接通过 HTTP 方式与 Consul 进行交互;然后我们会通过 Go Kit 框架提供的 Consul Client 接口实现与 Consul 之间的交互,并比较它们之间的不同。

前面两篇文章,我们了解完整个微服务结构,编写了核心的 ConsulClient 接口的实现,完成这个简单微服务和 Consul 之间服务注册与发现的流程。本文将会介绍服务下线注销和服务发现的实现。服务注册与发现组件,在各个服务实例注册到其上之后,将会向服务调用方提供所需请求调用的服务实例信息。

下面将会具体实现服务注销和服务发现的功能。

服务注销

接着前面的内容,我们实现服务注销方法 DeRegister,使得服务在关闭之前主动向 Consul 发送注销请求,代码如下所示:

代码语言:javascript
复制
func (consulClient *ConsulClient) DeRegister(instanceId string, logger *log.Logger) bool {

 // 1.发送注销请求
 req, err := http.NewRequest("PUT",
  "http://" + consulClient.Host + ":" + strconv.Itoa(consulClient.Port) + "/v1/agent/service/deregister/" +instanceId, nil)

 client := http.Client{}
 resp, err := client.Do(req)

 if err != nil {
  log.Println("Deregister Service Error!")
 }else {
  resp.Body.Close()
  if resp.StatusCode == 200{
   log.Println("Unregister Service Success!")
   return true
  }else {
   log.Println("Deregister Service Error!")
  }
 }
 return false
}

服务下线的逻辑相当简单,只需要将服务实例ID提交到 /v1/agent/service/deregister/ 路径下即可。在 main 函数中我们监控了 ctrl + c 的系统信号,在服务关闭之前会调用 closeServer 方法注销服务和关闭 web 服务。通过命令行启动服务,在 Consul 中观察到注册上去的 SayHello 服务后,我们发送 ctrl + c 组合键关闭服务,可以看到以下的命令行输出:

代码语言:javascript
复制
^C2021/07/08 21:25:40 Deregister Service Success!
2021/07/08 21:25:40 Service is going to close...
2021/07/08 21:25:40 Closed the Server!

以上输出告诉我们服务实例注销成功。回到 Consul 中,可以看到 SayHello 的服务实例确实已经不存在了,如图所示:

服务发现

服务发现的关键是获取到对应服务的服务实例信息列表,然后根据一定的负载均衡策略选择具体的服务实例发起调用。DiscoverServices 方法的作用是从 Consul 中获取到对应服务的服务实例信息列表,代码如下所示:

代码语言:javascript
复制
func (consulClient *ConsulClient) DiscoverServices(serviceName string) []interface{} {

 // 1. 从 Consul 中获取服务实例列表
 req, err := http.NewRequest("GET",
  "http://" + consulClient.Host + ":" + strconv.Itoa(consulClient.Port) + "/v1/health/service/" + serviceName, nil)

 client := http.Client{}
 resp, err := client.Do(req)

 if err != nil {
  log.Println("Discover Service Error!")
 }else if resp.StatusCode == 200 {

  var serviceList [] struct {
   Service InstanceInfo `json:"Service"`
  }
  err = json.NewDecoder(resp.Body).Decode(&serviceList)
  resp.Body.Close()
  if err == nil {
   instances := make([]interface{}, len(serviceList))
   for i := 0; i < len(instances); i++ {
    instances[i] = serviceList[i].Service
   }
   return instances
  }
 }
 return nil

在 DiscoverServices 方法中,我们将服务名提交到 Consul 的 /v1/health/service/ 路径下即可获取到对应的服务实例信息列表。我们将得到的服务实例信息列表的 JSON 数据用原先定义的 InstanceInfo 结构体进行解析,就能获取到对应服务实例的 Host 和 Port 等用于服务调用的关键元数据。

在 main 函数中,我们定义了用于获取服务实例信息列表的 /discovery 端点,通过本机的 IP 和 Port 访问该接口,如笔者的 IP 为 10.93.246.254(可在 Consul 的服务页中查看),查询的服务名为 SayHello,那么请求路径为 http://10.93.246.254:10086/discovery?serviceName=SayHello,即可获取到 SayHello 服务注册到该 Consul 节点的所有服务实例信息,如下所示:

代码语言:javascript
复制
[
    {
        "ID": "71370f60-a76d-4ca8-9631-fb6ec49648ec",
        "Service": "SayHello",
        "Name": "",
        "Address": "10.93.246.254",
        "Port": 10086,
        "EnableTagOverride": false,
        "Check": {
            "DeregisterCriticalServiceAfter": "",
            "HTTP": ""
        },
        "Weights": {
            "Passing": 10,
            "Warning": 1
        }
    }
]

小结

本文主要实现了微服务实例与 Consul 交互过程,包括服务实例的注销、服务发现。

通过三篇文章,我介绍了基于 Consul 自定义实现 Go 的服务注册与发现。这部分代码的实现,你可以封装成包进行调用,加入自己自定义的功能和用法。

完整代码,从我的Github获取,https://github.com/longjoy/micro-go-book

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 aoho求索 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 服务注销
  • 服务发现
  • 小结
相关产品与服务
微服务引擎 TSE
微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档