专栏首页aoho求索如何在 Go-kit 和 Service Mesh 中进行服务注册与发现?

如何在 Go-kit 和 Service Mesh 中进行服务注册与发现?

Service Mesh 作为下一代的微服务架构,它将服务间的通信从基础设施中抽离出来,达到交付更可靠的应用请求、监控和控制流量的目的。Service Mesh一般与应用程序一同部署,作为“数据平面”代理网络以及“控制平面”代替应用与其他代理交互。Service Mesh 的出现让业务开发人员从基础架构的底层细节中解放出来,从而把更多的精力放在业务开发上,提高需求迭代的效率。

本文我们将使用 Go-kit 提供的服务注册与发现工具包完成服务注册与发现,并介绍 Service Mesh 中 Istio 是如何进行服务注册与发现的。

使用 Go-kit 服务注册与发现工具包

自主开发服务注册与发现客户端固然能够加深我们对「微服务」「服务注册与发现中心」交互流程的理解,但同样会增加开发人员的理解成本,比如要了解服务注册与发现中心对外提供的接口、提交数据的具体细节,以及在服务注册与发现中心版本升级迭代或者 API 发生更新时,还需要持续维护客户端代码以避免不可用情况的发生,等等。

「Go-kit 作为一套微服务工具集」,意在帮助开发人员解决微服务开发中遇到的绝大多数问题,让他们更专注于业务开发。

Go-kit 提供了诸多服务注册与发现组件的客户端实现,支持包括 Consul、Etcd、ZooKeeper和 Eureka 在内的多种服务注册与发现中心。下面我们以 Consul 为例,实践如何使用 Go-kit 的 sd 包「简化」微服务服务注册与发现的实现。

sd 包中提供如下注册和注销接口,代码如下所示:

type Registrar interface {
Register() // 服务注册
Deregister() // 服务注销
}

在 Go-kit 中,我们根据选定的服务注册和发现组件,实例化Registrar接口对应的结构体实现,即可使用同样的接口进行服务注册和服务注销。接下来我们实例化 sd/consul 包下的 Registrar 用于完成与 Consul 的交互,实例化代码如下:

func NewDiscoveryClient(host string, port int, registration *api.AgentServiceRegistration) (*DiscoveryClient, error) {
config := api.DefaultConfig()
config.Address = host + ":" + strconv.Itoa(port)
// 生成 hashicorp client
client, err := api.NewClient(config)
if err != nil{
return nil, err
}
// 使用 hashicorp client 生成 sd consul client
sdClient := consul.NewClient(client)
return &DiscoveryClient{
client: sdClient,
config: config,
registration: registration,
register: consul.NewRegistrar(sdClient, registration, log.NewLogfmtLogger(os.Stderr)),
}, nil
}

DiscoveryClient.register 即最终实例化的 Consul 注册器。从实例化的过程可以发现 ConsulRegistrar的实现依赖于 sd.consul.Client,而 sd.consul.Client 实现依赖于 hashicorp client,即 Consul 的官方实现客户端。深入 hashicorp client 客户端中的服务注册与发现的实现,会发现它也是通过请求 Consul Agent 提供的 HTTP API 完成的,实现的方式与我们在上一课时中的实践大同小异。api.AgentServiceRegistration 结构体即需要提交到 Consul中的服务实例信息,包含服务名、服务实例ID、服务地址和服务端口等基本信息。

然后我们的服务注册和服务注销实现就可以委托给 Register 执行,如下所示:

func (consulClient *DiscoveryClient) Register(ctx context.Context) {
consulClient.register.Register()
}
func (consulClient *DiscoveryClient) Deregister(ctx context.Context) {
consulClient.register.Deregister()
}

服务发现的实现也是直接调用 sd.consul.Client 提供的相关方法。通过使用 Go-kit 提供的 Consul 工具包,可以在不了解微服务与 Consul 具体交互逻辑的基础上,通过简单调用包中提供的方法即可完成服务注册与发现,大大减轻业务人员的开发工作。

Service Mesh 中Istio 服务注册与发现

「Istio 作为 Service Mesh 的落地产品之一,依托 Kubernetes 快速发展,已经成为最受欢迎的 Service Mesh 之一」。Istio 在逻辑上分为数据平面和控制平面。

  • 「数据平面」,由一组高性能的智能代理(基于 Envoy 改进的 istio-proxy)组成,它们控制和协调了被代理服务的所有网络通信,同时也负责收集和上报相关的监控数据。
  • 「控制平面」,负责制定应用策略来控制网络流量的路由。

Istio 由多个组件组成,核心组件及其作用为如下:

  • 「Ingressgateway」,控制外部流量访问 Istio 内部的服务。
  • 「Egressgateway」,控制 Istio 内部访问外部服务的流量。
  • 「Pilot」,负责管理服务网格内部的服务和流量策略。它将服务信息和流量控制的高级路由规则在运行时传播给 Proxy,并将特定平台的服务发现机制抽象为 Proxy 可使用的标准格式。
  • 「Ci「「t」」adel」,提供身份认证和凭证管理。
  • 「Galley」,负责验证、提取、处理和分发配置。
  • 「Proxy」,作为服务代理,调节所有 Service Mesh 单元的入口和出口流量。

image.png

这其中 Proxy 属于数据平面,以 Sidecar 的方式与应用程序一同部署到 Pod 中,而 Pilot、Citadel 和 Galley 属于控制平面。除此之外,Istio 中还提供一些额外的插件,如 grafana、istio-tracing、kiali和prometheus,用于进行可视化的数据查看、流量监控和链路追踪等。

Istio 默认提供了以下几种安装 profile 形式,它们开启的组件配置如下表所示(+ 表示开启,空白表示未开启,- 表示未知):

****「配置」

「default」

「demo」

「minimal」

「remote」

「empty」

「preview」

组件/插件

Ingressgateway

+

+

+

-

Egressgateway

+

-

istiod

+

+

+

-

grafana

+

-

tracing

+

-

kiali

+

-

prometheus

+

+

-

这其中,istiod 组件封装了 Pilot、Citadel 和 Galley 等控制平面组件,将它们进行统一打包部署,降低多组件维护和管理的困难性。从上表可以看出,demoprofile是功能最全的配置清单,适合于学习和功能演示。previewprofile将可能使用一些开发阶段的测试组件,开启的组件不定。官方推荐使用 defaultprofile进行安装,因为它在核心组件和插件上做到了最优的选择,比如组件只开启了Ingressgateway 和 istiod,插件只开启了 prometheus。

当然我们也可以根据实践的需求选择合适的profile进行安装启动,比如下面的安装命令我们使用的是 demoprofile:

istioctl manifest apply --set profile=demo

上述命令以 demoprofile部署 Istio,该配置下的 Istio 能够通过可视化界面监控 Istio 中应用的方方面面。Istio 以 Sidecar 的方式在应用程序运行的 Pod 中注入 Proxy,全面接管应用程序的网络流入流出。我们可以通过标记 Kubernetes 命名空间的方式,让 Sidecar 注入器自动将 Proxy 注入在该命名空间下启动的 Pod 中,开启标记的命令如下:

kubectl label namespace default istio-injection=enabled

上述命令中,我们将 default 命名空间标记为 istio-injection。如果不想开启命令空间的标记,也可以通过 istioctl kube-inject 为 Pod 注入 Proxy Sidecar 容器。接下来,我们就为 register 服务所在的 Pod 注入 Proxy,启动命令如下:

istioctl kube-inject -f register-service.yaml | kubectl apply -f -

register 服务的 yaml 配置如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: register
  labels:
    name: register
spec:
  selector:
    matchLabels:
      name: register
  replicas: 1
  template:
    metadata:
      name: register
      labels:
        name: register
        app: register  # 添加 app 标签
    spec:
      containers:
        - name: register
          image: register
          ports:
            - containerPort: 12312
          imagePullPolicy: IfNotPresent
          # ... 省略环境配置
---
# 添加 Service 资源
apiVersion: v1
kind: Service
metadata:
  name: register-service
  labels:
    name: register-service
spec:
  selector:
    name: register
  ports:
    - protocol: TCP
      port: 12312
      targetPort: 12312
      name: register-service-http

这主要的改动有:为 register 服务添加 Deployment Controller,添加了新的标签 app,以及为 register 添加相应的Service资源。如果在部署 Istio 时启动了 kiali 插件,即可在 kiali 平台中查看到 register 服务的相关信息,通过以下命令即可打开 kiali 控制面板,默认账户和密码都为 admin:

istioctl dashboard kiali

image.png

从上图可以看出在kiali 控制台中存在多个维度查看 Istio 中部署的应用:

  • 「Overview,网格概述」,展示 Istio 内具有服务的所有命名空间;
  • 「Graph,服务拓扑图」
  • 「Applications,应用维度」,识别设置了 app 标签的应用;
  • 「Workloads,负载维度」,检测 Kubernetes 中的资源,包括 Deployment、Job、DaemonSet 等,无论这些资源有没有加入 Istio 中都能检测到;
  • 「Services,服务维度」,检测 Kubernetes 的 Service;
  • 「Istio Config,配置维度」,查看 Istio 相关配置类信息。

register 服务启动后,我们在Applications、Workloads、Services维度中均可查看到 register 的身影,如下 Applications 维度图所示:

image.png

Istio 依托 Kubernetes的快速发展和推广,对 Kubernetes 有着极强的依赖性,其服务注册与发现的实现也主要依赖于 Kubernetes 的 Service 管理。我们可以通过以下这张图理解 Istio 的服务注册与发现。

image.png

通过该逻辑图,我们可以看到 Istio 服务注册与发现主要有以下模块参与。

  • 「ConfigController」:负责管理配置数据,包括用户配置的流量管理和路由规则。
  • 「ServiceController」:负责加载各类 ServiceRegistry,从 ServiceRegistry 中同步需要在网格中管理的服务。主要包含:①KubeServiceRegistry,从 Kubernetes 同步 Service 和 Endpoint 到 Istio;②ConsulServiceRegistry,从 Consul 中同步服务信息到 Istio;③ExternalServiceRegistry,监听 ConfigController 中的配置变化,获取 ServiceEntry 和 WorkloadEntry 资源并封装成服务数据提供给 ServiceController。
  • 「DiscoveryServer」:负责将 ConfigController 中的路由配置信息和 ServiceController 中的服务信息封装成 Proxy 可以理解的标准格式,并下发到 Proxy 中。

Pilot 组件会从各个 Service Registry,比如 Kubernetes 中的 Service 和 Consul 中注册的服务,采集可用的服务数据到 Istio 中,并将这些服务转换为 Proxy 可理解的标准服务格式,下发到 Proxy,同时下发的还有用户预先配置的路由规则和流量控制策略。在被代理的应用根据服务标识发起 HTTP 通信时,Proxy 将会从拦截的网络请求中根据服务标识获取对应的服务数据,并根据下发的路由规则选择合适的实例转发请求。

基于 Kubernetes 迅速发展的 Istio 在服务注册与发现组件上支持最完善的自然也为 Kubernetes,这依托于 Kubernetes 对 Pod、Service 等资源的监控,为服务之间的调用提供弹性、负载均衡、重试、熔断和限流等诸多保障。

而对第三方服务注册与发现组件的集成和支持,比如 Consul 等,Istio 官方的实现仅仅是基本可用的级别,在性能和易用性方面仍需要不断进行打磨和测试。「因此,在 Istio 的落地实践中,建议是与 Kubernetes 强绑定使用,「「以」」达到功能的最优化发挥。」

小结

服务注册与发现是微服务架构落地实践的基石之一,因为有中心化的服务注册与发现中心管理大量动态变化的服务实例,使得应用服务可以在无太大压力的条件下进行微服务拆分和横向扩展,大大提升了微服务架构的灵活性和伸缩性。

本文我们首先介绍了 Go-kit 中服务注册与发现工具包,并使用其中的 Consul 工具包改善了 register 服务的服务注册与发现的实现。接着我们介绍了 Service Mesh 中的佼佼者Istio,以及其服务注册与发现的实现。Istio 本身并不提供服务发现的能力,但是它可以依托Kubernetes 或者第三方的服务注册中心获取服务信息列表,并根据设定的路由规则进行有效的动态调用。希望通过本文章的学习,不仅能加深你对 Go 微服务中服务注册与发现的认识,也能了解到 Istio 是如何在代理层实现服务注册与发现。

本文分享自微信公众号 - aoho求索(aohoBlog),作者:cangwu

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-05-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 华为多年实践:ServiceComb在Service Mesh的探索与思考

    内容来源:2018 年 6 月 27 日,华为微服务架构师田晓亮在“LC3微服务Workshop | 深入解读ServiceComb”进行《ServiceCom...

    IT大咖说
  • 构建基于Service Mesh 的云原生微服务框架

    ? 目前很多企业还是采用基于 SDK 的传统微服务框架进行服务治理,而随着 Service Mesh 的普及,越来越多的企业开始布局自己的 Service M...

    腾讯云中间件团队
  • 构建基于Service Mesh 的云原生微服务框架

    腾讯为了解决以上的技术问题,自研了 TSF Mesh 微服务框架。也许有人会问,开源 Istio 已经是比较完善的 Service Mesh 方案了,为什么要再...

    深度学习与Python
  • Chaos Mesh® 的 Chaos Engineering as a Service 探索之路

    近日,由 TiDB 社区主办,专属于全球开发者与技术爱好者的顶级挑战赛事——TiDB Hackathon 2020 比赛圆满落幕。今年是 TiDB Hackat...

    CNCF
  • Chaos Mesh® 的 Chaos Engineering as a Service 探索之路

    Chaos Mesh 已经开源一周年了,目前是 CNCF 的 sanbox 项目,在国内外发展良好,有了很多的 Contributor 和关注度。

    PingCAP
  • 干货|如何步入Service Mesh微服务架构时代

    大家好!我是"无敌码农",今天要和大家分享的是关于新一代微服务架构——Service Mesh的具体玩法!在微服务架构盛行的今天,作为一名互联网技术从业人员,对...

    用户5927304
  • Weibo Mesh的发展

    微博从2013年开发了Java语言的Motan RPC框架,基于此完成了服务化改造。Motan从2013年上线至今经历过每个热点事件,三节高峰的挑战,稳定性和可...

    春哥大魔王
  • 天池中间件大赛Golang版Service Mesh思路分享(作者:我的 96 年表弟)

    这次天池中间件性能大赛初赛和复赛的成绩都正好是第五名,出乎意料的是作为Golang是这次比赛的“稀缺物种”,这次在前十名中我也是侥幸存活在C大佬和Java大佬的...

    芋道源码
  • go-kit 构建微服务(1)

    Go是一种很好的通用语言,但是微服务需要一定量的专门支持。RPC安全性、系统可观察性、基础设施集成,甚至程序设计等都需要认真考虑。go-kit工具包填补了标准库...

    Johns
  • dubbo-go介绍

    dubbo-go 是目前 Dubbo 多语言生态最火热的项目。dubbo-go 最早的版本应该要追溯到 2016 年,由社区于雨同学编写 dubbo-go 的初...

    heidsoft
  • 天池中间件大赛Golang版Service Mesh思路分享

    这次天池中间件性能大赛初赛和复赛的成绩都正好是第五名,出乎意料的是作为Golang是这次比赛的“稀缺物种”,这次在前十名中我也是侥幸存活在C大佬和Java大佬的...

    涤生
  • 研究consul的service mesh功能

    来源:https://jeremy-xu.oschina.io/2018/07/%E7%A0%94%E7%A9%B6consul%E7%9A%84service...

    程序猿DD
  • consul的service mesh功能初体验

    |作者简介 ? consul之前一直被当成一个服务发现、分布式KV服务、服务健康检查服务等,但此前发布的1.2版本,宣称其实现了Service Mesh方案。...

    腾讯云TStack
  • service mesh - 微服务通信进化之路

    ? 导语 | service mesh 致力于做微服务时代的 TCP,以 TCP 的方式解决微服务的通信问题。那么它解决的是微服务时代的什么问题?以及以何种方...

    腾小云
  • dubbo-go 的开发、设计与功能介绍

    dubbo-go 是目前 Dubbo 多语言生态最火热的项目。dubbo-go 最早的版本应该要追溯到 2016 年,由社区于雨同学编写 dubbo-go 的初...

    Java帮帮
  • Go 语言入门系列:Go 语言:环境安装

    「最近将会更新 Go 语言入门的系列文章,非常基础。适合小白入门或者零基础的同学,已有相关 Go 基础的同学可以略过。」

    aoho求索
  • 开源推荐 - Swoft 2.0.3 重大更新,发布优雅的微服务治理

    Swoft 是一款基于 Swoole 扩展实现的 PHP 微服务协程框架。Swoft 能像 Go 一样,内置协程网络服务器及常用的协程客户端且常驻内存,不依赖传...

    猿哥
  • Swoft 2.0.3 重大更新,发布优雅的微服务治理

    Swoft 是一款基于 Swoole 扩展实现的 PHP 微服务协程框架。Swoft 能像 Go 一样,内置协程网络服务器及常用的协程客户端且常驻内存,不依赖传...

    桶哥
  • 干货 | 快速融入云原生,携程开源 Dubbo for Go 版本

    何鑫铭,携程基础中台研发部技术专家,dubbo-go 主要作者。目前专注于 Golang & Java、中台架构、中间件与区块链等技术。

    携程技术

扫码关注云+社区

领取腾讯云代金券