Bookinfo——基于 CloudWeGo 重写 Istio 经典 demo

CloudWeGo Study Group 是由 CloudWeGo 社区发起的学习小组,开展以 30 天为一期的源码解读和学习活动,帮助新成员融入社区圈子,和社区 Committer 互动交流,并学习上手 CloudWeGo 几大框架项目。目前 CSG 第四期—— CloudWeGo 业务实践案例解读已经正式启动!

本期活动期间将会安排 4 期直播分享,主题分别为:

  • Bookinfo——基于 CloudWeGo 重写 Istio 经典 demo
  • Open Payment Platform——基于 CloudWeGo 实现 API Gateway
  • EasyNote——CloudWeGo 生态入门
  • BookShop——从上手电商到上手CloudWeGo

本文为 CSG 第四期第一场直播中字节跳动基础架构研发工程师胡文分享内容。

回放链接:https://meetings.feishu.cn/s/1ipd8ih057fnm?src_type=2

一、嘉宾介绍

本期分享的内容主要分为以下四个部分:

用 Hertz 和 Kitex 重写经典的 Bookinfo 项目,展示工程设计、技术选型,再由浅入深展示用全链路泳道来实现灰度发布等场景。

  1. 工程设计介绍
  2. 技术选型介绍
  3. 全链路泳道介绍
  4. Proxyless 与 ServiceMesh

大家晚上好,非常感谢大家能够参加我的分享。这次分享主题是 Bookinfo —— 基于 CloudWeGo 这套技术栈如何去重写 Istio 最经典的一个 demo 应用。 整个这次分享会分为 4 个章节:

  • 第一章节会简单介绍一下这个项目的工程设计;
  • 第二章节介绍我们做这个项目的技术选型的思路;
  • 第三章节是我们这个项目最核心的要实现的能力,也是这个 demo 的核心目标:使用 CloudWeGo 这套技术栈帮我们去演示如何去做一个全链路的泳道;
  • 第四章节会做一些技术上的延伸的讨论,就是 Proxyless 与 ServiceMesh 模式的一些思考。

二、工程设计介绍

项目介绍

首先介绍一下项目,Bookinfo 是 Istio 官方提供的经典 demo 应用,它的目的是演示 Istio 的各种各样特性。当然我们目的其实也是类似的:我们希望使用 CloudWeGo 技术栈来重写这个 demo,并且基于 CloudWeGo 本身提供的技术栈,跟生态怎么做结合,去演示如何满足微服务场景上的需求。这里也放了我们项目的地址,大家感兴趣可以点击看一下。

项目地址:https://github.com/cloudwego/biz-demo/tree/main/bookinfo

架构设计

整体的架构设计和 Bookinfo 保持一致,从下图自上往下看,首先上面会有一层控制面,控制面是直接复用 Istio 的控制面,就是 Istiod;从左往右,左边会有一个入口网关,右边就是我们 Bookinfo 的主体的一个微服务的拆分。首先左边的一个服务是 Producpage,它负责接收外部的 HP 请求流量,然后去做相应的页面呈现,以及相应接口的聚合。后面会拆分几个服务,一个是 Reviews,而 Reviews 他会去调用 Ratings 服务去获取书评的评分,然后还拆分了 Details 服务, Details 服务就是去把一个数的详情信息做一个展示。

图上我们也按照流量的示意图画了流量是如何是走向的,分两种情况,因为 Bookinfo 最主要是 demo 下全链路泳道,所以我们会有两种类型的流量,一种是带染色标识的流量,我们会走到一个像紫色的这条带了流量染色标识的。首先它经过我们的入口网关,它会在入口网关统一做一层流量的染色。后面的所有的请求都会带上相应的 baggage。这边 baggage 我们目前是通过 OpenTelementry 的 changing 能力帮我们自动去透传的。 下游的服务都会集成 Kitex 的 xDS 套这套 SDK,在 Client 做路由的时候,就会精准地把流量按照泳道的路由规则,把流量打到具体的某个服务实例版本上。比如紫色这条,它会精准地打到 Reviews v2上,也会继续往下打到 Ratings v2。 如果它没有带染色标识,它是一个正常请求的话,我们的泳道规则定义正常的它会正是会在 v1 和 v3 版本做之间做一个 Round-robin 轮询,也会去调用我们的 Details。Ratings 这边,是让它固定去请求 v1 版本的服务,可以看到,每个 Productpage 或 Reviews,都集成了 xDS 的库,它会跟控制面 Istiod 建立 xDS 的长链接,在 Istio 控制台上可以去配置路由服务治理的规则,通过 xDS 通道动态地下发到服务实例上。

工程架构设计

刚刚介绍了整个工程的大概的架构设计,这个是整个工程的目录结构设计。目录结构是参考比较火的 go standard project layout 项目的推荐。

首先从上往下,会放一个 makefile, makefile 是整个工程构建的一个入口,可以理解相应的构建的命令都是统一封装,会相应的构建,都可以通过一些封装指令去做相应的执行

build 目录主要会放工程相应的镜像构建的一些配置文件,比如 Dockerfile

cmd 可以理解成是整个工程的主干入口,每个服务使用 Cobra 把它拆分成不同的 subcommand;

conf 目录就是存放整个工程的一些配置文件

Idl 目录会存放 Kitex 的Thrift 的定义 internal 是业务逻辑相关的封装,我们统一它默认是不会对外提供包的暴露的,所以我们把它统一放到 internal 里面。 internal 里面也会简单做一些分层: handler 层是用统一放 Hertz 相关的一些 HB 的 handler;server就是相应的我们 4 个服务相应的服务的一些初始化,以及它的服务启动的相关的一些逻辑service。我们一些业务逻辑的封装都会统一放在我们这 4 个微服务的一些相关的业务逻辑的实现,都会统一放在这边。 kitex_gen 就是基于 IDL 去自动生成的一些代码

Manifest 是工程部署相关的配置文件,正常部署比较推荐的使用 Helm Charts 来部署。这边也是有一个 Bookinfo 的 helm charts,可以直接去 helm install 去部署应用

pkg 可以理解成高度封装、外部可以高度复用的并且跟业务逻辑没有任何没有太大的耦合的一些可复用的包,我们会统一把它放到 pkg 里面

OK,这便是 Bookinfo 大概的工程结构设计

Makefile 规范设计

讲到工程化肯定就离不开 Makefine,刚刚我们也讲到,它是做整个项目构建的一个指令封装,其实可以理解也是我们内部抽象出来的一套规范。我们会要求每个项目的 Makefine 得包含一些必要的元素,比如必须得能够支持代码的检查,也能支持去执行一些单元测试,能支持去做二进制的构建、跨平台编译的二进制构建,以及我们的容器的镜像的构建,还有构建完镜像之后,能够支持我们 push 到远程的镜像仓库上,也允许把一些本地构建的产物能够比较方便地清理掉。

上面所说是一个“强需”,即需要包含这些。下面可以按自己的需求,看是否去添加一个端到端的的测试。

这个是 Makefine 的规范设计,也给大家简单地分享一下。 接下来是一个 Makefine 的具体的例子。可以看到,我有一个基于 lint 做代码检查的,还有一个是单元测试的,还有个是本地化二进制产物构建的,还有就是一个容器化镜像构建的。

另外一块就是提到工程化,因为现在都是一个云原生的时代,大家都是以容器化的方式去运行自己的应用,所以容器的 Dockerfile 编写其实也有相应的规范的要求,会要求按照不同的阶段去做对应的 Dockerfile 做个拆分。

  1. 第一,多阶段构建。首先可以看上面其实是一个编译期的阶段,编译期的阶段可以依赖 golang 的基础镜像去执行我们刚刚 makefile 里面封装的二进制构建。它的任务其实就是把我们的工程编译成一个可执行的二进制。

  1. 第二,镜像精简原则。关于运行时的镜像,就会很轻量,它不会基于一个包含了 Golang 或者包含一些基础的较大依赖的基础镜像,它会只会希望是依赖一些轻量的、小的基础镜像,我们会把第一步的建产物 copy 到镜像里面去,并且把一些配置目录准备好。所以它只需要放一些可执行的二进制文件和配置目录即可。这是多阶段构建的一个规范的设计。刚有提到运行时的镜像,我们尽量希望它在生产环境是尽量精简轻量的。所以基础镜像中放的东西尽量是越少越好。
  2. 第三,镜像安全。通常业务不需要特权执行,所以我们会要求用户使用,由此命令版切换到非 root 用户,避免在生产环境把 root 用户暴露出去。

三、技术选型介绍

技术选型方面,我简单的把 Bookinfo 项目的技术栈大概列了一下。

  1. 首先,Kitex 和 Hertz。技术栈从上往下是我们服务的框架,Productpage 是对外提供 HTTP 服务的,所使用 Hertz 来写一个 server 端,并且它也集成了 kitex client 去调用相应链路下游的服务。比如他调用 Reviews,调用 Details,都会使用 kitex client 去调用其他的服务。并且这些因为都是内部的一些微服务,它不需要暴露接口的外部,所以统一使用 kitex 封装成 RPC 服务。

  1. 第二,Istio。刚有提到,我们这个项目是为了去演示在服务网格下怎么使用 proxyless 去做全链路的泳道,所以我们也会依赖 Istio 的控制面。它的职责主要是用来做服务网格控制面,跟数据面的 xDS 模块做交互,负责把一些 xDS 的配置动态下发下来。
  2. 第三,Wire。我们工程里面也依赖 Google 的 wire 去做相应的依赖注入。
  3. 第四, OpenTelementry 。因为我们要做全链路的泳道,首先 Tracing 可能会是一个强依赖要依赖 Tracing 的上下文透传能力,帮我们去把泳道的染色标识透传下去,并且也顺带去把全链路的 tracing、metrics、logs 都集成演示了。
  4. 第五,Kitex-xDS 。是工程一个比较核心的依赖,能够让 Kitex 以 Proxyless 的方式能够直接对接到无网格的体系中去。
  5. 最后,就是用 react,arco-design 去写了一个简单的 UI 层。 以上是技术栈的简单介绍

框架选型 - Hertz、Kitex

框架选型刚刚有提,就不再过多赘述了。首先, Productpage 有使用的 Hertz server,其他的都是用 Kitex。

依赖注入(Google Wire)

刚刚有聊到,会依赖一个 Google 的 wire 来做依赖注入。 Google 的 wire,我相信大家也比较了解,像在 go 的依赖注入这块,主要分两种:一种是运行时基于反射去做,还有一种是在编译期能够去基于静态的代码分析和代码生成的机制去提前把相应的注入代码生成好。

我们选型的是使用 Google wire,可以看到一个简单的handler。handler 有两个依赖,一个是 review 的client, detail 的 client 可以看到 handler 它其实不用关心这两个 client 是怎么去初始化的,它只需要把这两个 client 作为它的一个依赖,声明在这边即可。

下面就是 review client 它本身的 provider,也不需要关心谁在谁会去使用它,只需要把它自身怎么初始化,以及自身怎么对外提供服务,提供能力的封装好。可以看到二者的职责是可以分离的。

下图就是 review client 它自身的 provider 例子

这边就开始注入了,用 wire.Build 去做,会把相应的 provide 以及依赖声明都统一声明在这。

我们执行 go generator,会帮我们自动生成相应的依赖注入代码。可以看到,依赖注入代码会帮我们生成,比如初始化 review client、 初始化 detail client,把这 client 作为它的参数传递进去。正常没有依赖之后,这些代码可能需要我们反复地去手写,Bookinfo 这个项目比较小,可能还好。如果是一个比较大的工程,这些代码如果手写很容易顺序会有问题,或者是一个重复的工作,不是那么简单或者优雅。

可观测 - OpenTelemetry

另外一块就是可观测了,我们的选型是使用 OpenTelementry 。 简单介绍一下,OpenTelementry 是一套可观测的开源标准协议,它提供了相应的 specific,以及提供了相应 API 的统一定义,包括基于它自身的 specific 和 API 定义也实现了一套 SDK,同时也包括了一套自己实现的数据收集器,比如能够帮我们从云上或者基础设施里面去采集一些数据,这些数据主要包括Metrics、 Traces 和 Logs,这些统一地把它们收敛成自己的协议规范格式。这个是 OpenTelementry 的简单介绍。

另外一方面,就是我们的 Kitex 和 Hertz 已经是原生集成了 OpenTelementry 。这边有两个 repo,大家感兴趣可以点过去看一下具体的实现。有了这些库,我们使用 Kitex 或者 Hertz 的时候,就可以比较轻松地直接在我们业务中去集成 OpenTelementry。

集成的代码在下边简单列了一下,其实也比较简单,一个是初始化相应的 OT 的provider,并且把相应的 tracing 的 Suite 注入到 server 端去就可以了。这样其实就会帮我们把 Tracing、Metrics、Logs 的一些集成自动帮我们做掉。

这个是可观测,简单演示一下集成之后的效果。

有一点可以提一下,单独讲一下 Kitex 和 Hertz ,它底层的 Tracer 的实现都比较优雅,会把一些框架内部的细节帮我们以 stats 的方式暴露出来。这样我们上层在使用 OT 去集成的时候,就能很轻松地把这些事件作为一个 span 的 event 去帮助用户把它暴露出来,在 event 上做相应的呈现,比如一个客户端的连接的建立和结束,以及他的读写事件,我们都能够在链路跟踪里面去观察到,并且会生成一些指标的拓扑或者调用链。

服务治理 - xDS 介绍

服务治理我们的选型思路就是基于 Istio 这套服务网格的机制来做。首先要讲服务网格,需要跟大家介绍一下 xDS 这个概念。 xDS 简单理解就是一组发现服务的总称,所以它叫“x”。其中,比如LDS、RDS、CDS、EDS,就是各种各样的资源自动配置的服务发现,它们都能够在我们的控制面,跟 Istio 里面能够跟我们的数据面实时地进行配置的下发。

有了 xDS 这套机制或这套统一的抽象,事情就比较好做。 Kitex 要想去对接,就可以有一种思路:直接去跟 Istiod 交互,基于 xDS 这套通用标准的协议,去实时地去获取我们想要的治理规则配置。

服务治理 - Kitex xDS

Kitex 现在也已经原生地支持了 xDS API,所以我们可以直接在我们的代码里面去开启相应的 xDS 模块,并且可以让服务以 Proxyless 的模式运行,再统一被服务网格去纳管。具体内部的实现细节,有一些方案大家感兴趣可以看一下。 使用方面,可以看到有代码片段。我们首先要初始化我们的 xDS Manager,负责存放我们相应的 xDS 的配置,实时 watch 的一些配置信息,以及它会去内置一个 xDS client ,负责跟我们的控制面 Istiod 做实时的交互。看到我们的 kitex client 会去集成一个 xDS 的路由模块,这个是为了我们后面要做全链路泳道,埋下一个伏笔:我们怎么基于 Proxyless 去实现一个流量路由。

当然,同时要把 OpenTelementry 能力给开启。

基于 xDS,Kitex 可以统一地被服务网格纳管,统一纳管的好处就可以体现出来了:我们可以用 Istio 原生的 API 去定义治理规则。比如按照 Istio 常规的使用方式,会给每个实例打上一个版本标识,会定义一个 destination rule 去为我们每个实例做一个分组。在比如 v1 版本,v1 版本的 pod 统一把它放到 v1 的池子里, v2 版本统一放到 v2 的池子里面,相应的就是 v3 也会放到另外一个池子里面,是按服务实例去做一个简单的分组。

服务治理 - 定义流量路由规则

有了分组之后,就可以去定义分组的流量路由规则。路由规则是两条,第一条就是在 header 里有相应的 Baggage,会把流量精确地打到 Ratings 第二版本的池子里面,如果没有,会默认就打到 Ratings 所有版本里面轮询。这就是可以基于 Istio 原生的 API 去定义相应的流量的路由规则了,这是对接 xDS 的好处。

四、全链路泳道介绍

讲完了技术选型,并顺带引出了我们今天比较重要的一个主题:全链路泳道。我们做这个 demo 最主要的目的就是希望能够 demo 一下怎么去实现全链路泳道。

首先,泳道设计简单分了两个泳道,其实具体分多少泳道是跟泳道路由规则来定的。我们演示的其实是基准泳道,分支泳道。可以看到基准泳道是 product v1,它会在 v1 和 v3 之间做一个轮询,会打到 v1,如果带了相应 baggage v1 的版本的流量路由,会精确地路由到 v2 版本,并且也相应地录入到 Ratings v2 的版本。

泳道设计 - 传统流量路由方式

当我们接到这个泳道的需求,怎么去实现也有几种思路,其中最容易想到的就是传统的思路,其实 Istio 原生就支持按照一些 header 头去匹配,能够去定义路由规则。

有些业务直接按照业务属性标识,即我给你一个业务属性标识,你帮我去配一条路由规则。比如要求按照 uid=100 这条规则,让我们去配一条相应的路由规则。

偶尔这样一次没问题,但是如果又来下一个业务方,需要配一个 uid= 101 的,这样局限性就慢慢地显露出来了,非常不够通用。因为它是以业务具体属性的某个 key 作为流量路由的匹配规则,并且 key 也需要在 SDK 或者业务代码里面,相应的有一些侵入性,必须得帮它去透传业务属性的 key,要在 header 头里面。比如请求 service a 请求 service b, header 头里面需要带上 uid=100,这样 Istio 的路由能力帮你识别到 header 去路由。 另一方面,比如业务方今天是基于 uid= 100 这条规则,第二天又变化,这个路由规则也就很容易频繁地变动,每个服务配的 vs 可能都需要去频繁地去变动。而且维护的规则可能会随着服务数量,成了基数爆炸的局面,规则可能会非常的臃肿。这个是以传统的 Istio 默认提供的那种方式去实现的弊端。

泳道设计 - 流量染色

这里会考虑使用统一染色的概念,所谓的染色,比如我们刚说的 uid=100,只需要把变化的这版收敛在入口网关。下游不用感知具体业务的 header key 是什么,只需要知道你有没有带 Baggage, 具体配哪些 Baggage也不需要在业务代码里面去显示,比如我今天传 uid ,明天传 cookie 中的某个 key。业务方不需要跟着你一起去改动它,只需要去接入 Baggage 这套SDK,能够自动地去透传 Baggage。

所有的变化的部分都收敛在运维侧,只要配染色的规则以及路由规则就可以了。业务代码不需要做任何的变化,染色网关层通常会分两种染色方式,一种是按条件去染染色,比如刚刚说的按 uid = 100 这种,去打一个染色的标,或者它按某些 cookie 去做匹配,也打个染色的标。还有另外一种,按照一定的比例去做按比例请求,做一些染色的标识。比如我们按照 10% 的流量,我们去简单去做 10% 的流量染色。 基于这条染色标识,对比传统的方式,其实有很多好处,就是业务跟业务解耦,跟业务代码解耦开了。至于基于什么方式来实现 Baggage,以及 Baggage 本身怎么去透传,也是需要基础架构团队需要去考虑解决的问题。

泳道设计 - 染色标识全链路透传(Baggage)

我们的选型思路就是利用全链路的机制来做 Baggage。Baggage 其实也是全链路里孵化出的概念,本身设计出来就是为了能够让整个全链路可去透传一些业务属性自定义的 KV 属性,比如我们可以用它来传递染色标识,也可以传递一些业务的标识,比如 AcountID。所以业务方需要做的事情,只需要集成我们的 OpenTelementry 的 tracing 即可。

泳道设计 - 泳道效果(基准泳道)

接下来是 Bookinfo 的简单展示,比如入口流量不带 uid 请求,默认会找到基准泳道。基准泳道是两个不同的服务实例版本的实现,一是只返回新的一颗新的书评,还有一个是返回没有新的书评。另外一种,它的入口请求已经带了对应的 uid 标识,就会被精确地路由到分支泳道上。分支泳道就是一个返回 5 的评分服务。

五、Proxyless 与 ServiceMesh

以上给大家简单介绍一下,工程引申到了全链路的场景。可以再引申一波,思考一下 ServiceMesh 以及 Proxyless 这两个之间是什么样的关系,以及 Kitex xDS 怎么实现了全链路流量路由能力的,也可以给拿大家简单地去介绍一下内部的实现细节。

首先 Kitex Proxyless 的模式,可以看到整体的架构也会分控制平面以及数据面。可以看到,已经没有传统 Detail 的 envoy 或者 pilot agent、sidecar 。就是一个干净的业务 application,里面会集成 xDS 相应的模块。xDS 相应的模有一个 xDS client,做的事情就是跟 Istiod 去做通信。 基于 ADS 协议,能够去实时地获取到治理规则的变化,比如刚刚配的流量路由的规则,其实属于治理规则。未来可能还会去支持动态的熔断、超时,这些也是能够实时感知,实时下发下来,我们会把它 sync 到我们 xDS resource manager 中,维护实时的治理规则。

请求路径上,会发一个 request 到我们的一个 Upstream 服务上。 Upstream 服务可以给服务去做一些版本的划分,按照版本去划分成不同的实例组。可以理解成,如图示,把一个服务按照版本划分成了两个实例组。首先两个 endpoint,它属于 v1 版本,会放到 sub cluster a 里面, c 和 d 另外两个服务实例属于 v2 版本,会放到 subcluster b 里面。刚刚演示的流量泳道,本质就是去 pick subcluster 的,具体是要打到 v1 用池子里,还是打到 v2 池子里面,做的就是这个事情。 去做这个事情的大概链路,首先我们 Kitex client 会发起请求,它发起请求的时候,我们会有相应的 Middleware,它最先会经过一个 xDS 路由的 Middleware。它要做的事情,就是根控制面配置的路由规则,获取配置规则就从这里获取。我们会实时地去 sync,获取到治理规则之后,它知道这个请求,需要能够路由到 subcluster a 还是 subcluster b,其实都有相应的定义。它拿到这个信息之后,就知道了请求是要路由到 subcluster a,再经过一系列的中间件,比如在这些中间件里面,都可以去集成 Istio,有治理的逻辑,比如熔断、超时以及动态的负载均衡。 resolve middleware 要做的事情就是:因为我们已经选到了一个池子,池子里面有很多服务实例,具体要把流量打到哪个服务实例,其实就是 resolve 去做的,会去做一个 load balance,精准选择某个实例。经过 resolve 之后,可以拿到一个精确的 endpoint,就可以发一些请求了。然后它的 request 就会精确地打到 endpoint a 上,这就是一个完整的流量路由基于 Proxyless 实现一个全链路泳道。给大家简单分享了底层流量路由的实现原理。

标准 Sidecar 模式

这是 Proxyless 模式的 ServiceMesh 的形态,大家比较熟悉的 ServiceMesh 形态其实都是这种标准的 Sidecar 。每个服务我们都会给它注入一个 Proxy,这个 Proxy 就是基于 envoy 实现的。

它做的事情,首先容器会有一些,不管是 iptables 还是 eBPF,会帮我们把进去的流量能够动态地去劫持重定向到我们 Proxy上。 Proxy 处理完之后,把请求再重定向到业务容器上,业务容器发对外发出的 outbound 流量也会首先也会重定向到 Proxy 上。

相当于它的 inbound outbound 都会过一遍代理,相当于我们能够在业务进程、业务逻辑上再增加一层能够可拓展的中间件机制,我们所有队列建的中间层逻辑,比如指标、 tracing、 治理,还有安全,都统一可以收敛到这个 Proxy 中去实现。这跟 Middleware 思想很类似的,只不过 Middleware 和业务逻辑在同一个进程里面。 控制面都是基于标准的 xDS,基于标准的 Istiod 去做控制面。这个是业界比较熟悉或者用得比较多的,标准 sidecar 模式。

eBPF 内核 Mesh 模式 (cilium)

还有第三种,可能比较新的模式,基于 eBPF 内核去实现内核 Mesh 模式。它所谓的内核 Mesh 其实就是流量首先会经过我们。

简单介绍一下 eBPF 能实现的能力,它其实能够帮我们直接去内核态的一些系统函数去做一些相应的插桩。可以去动态地去插入一些你想要去执行的逻辑,比如我想去执行一些L3、 L4 的流量的代理,我可以把它使用 eBPF 去实现,这样就不需要去借助 envoy 去做 L3、L4 的 load-balancing,可以直接在内核里面去做。当然,有一些内核里面没法完成的,我们会把它 fallback 到用户态的一个 envoy 上。

图中这个是 cilium 社区目前实现的一套基于 eBPF 的内核 Mesh 模式。首先 eBPF Native 层会负责 L3、L4 的流量,或者一些 canary 或者 topology 感知路由、多集群的支持,还有安全、可观测性的支持。 可以看到,我们很多能力可以下沉到内核里面去,不需要在用户态的 envoy 里面去做。当然有一些跟用户态的属性强绑定的,比如 L7 的 load-balancing,跟用户带的框架或者协议都是强感知的,它很难在内核态实现,或者说要在内核态实现的成本会比较高,所以还是倾向于会把它 fallback 到用户态来做,包括我们的 L7 的 Rate Limiting,还有 TLS 的终止这些能力。这是一个基于内核的 Mesh 模式。

为什么要做,主要是出于性能的考量,因为 Sidecar 模式难免会带来一些时延的增长。虽然随着 Istio 和 envoy 本身的迭代,性能差距会越来越小。 所以问题来了,ServiceMesh 究竟是什么?现在仿佛有各种各样的模式,各种各样的组合方式。

这确实是一个问题,值得大家思考。

ServiceMesh —— 无关模式,服务间通信基础设施标准抽象

我的个人的思考,就是 ServiceMesh 其实不关心具体的模式实现细节,它其实是一层通信基础设施的抽象。你可以理解成,最早的时候,我们的业务代码想要去实现可观测,要实现流量路由,要实现安全或实现 Resilence,它要在自己的业务代码或者在自己业务框架的 Middleware 里面去做。

其实框架帮我们做了一层解耦,把业务不用写在业务函数里面,具体的业务逻辑里面,它抽象到框架的提供的 Middleware 里面去做。我理解它其实也是一层业务代码和基础设施的一些分离。Mesh 的核心其实就是把通用的标准基础设施能力下沉,可以下沉到我们的 Middleware,也可以一个 Sidecar 里面去,甚至下沉到内核 Mesh。 其实它们目的或者初衷,我理解其实都是一样,只不过是技术手段,或者根据不同场景能够去抉择不同的技术选型的差异,本质或者目标都是一样的。这个是我个人对 ServiceMesh 的个人理解。

ServiceMesh —— 基于统一标准去构建服务治理平台

基于这套理解,其实我们就可以去做一些有意思的事情了。比如有这套统一的标准,有一个统一的抽象。其实可以把控制面或者服务治理的规则模型统一起来,去统一各种不同的异构的框架或者异构的平台。自己描述自身的那些服务治理规则模型可能都不一样,可以统一起来,包括控制面也可以收敛在一起,不用不同的框架或者不同的体系、使用不同的控制面。其实上层运维人员或者用户,会有一种分裂的感觉,包括配置这些治理规则。

怎么动态下发下去,其实社区里 xDS 也是一个比较盛行的、标准的一套通用协议。刚刚提到异构的数据面,其实会有很多种,我们做我们要做的事情就是去兼容它,或者让它去贴合我们的整套体系的生态,比如标准的 Proxy 模式、Proxyless 模式,还有刚提到内核 Mesh 模式,它其都可以被统一纳管到一个统一的服务网格的体系中。以上便是我基于 ServiceMesh 的一些个人的理解。 最后就是我们项目相关的一些链接,感兴趣的同学可以点击链接到 GitHub,去看相应的一些项目。


项目地址

活动链接:https://github.com/cloudwego/community/issues/58

图片

全国首款支持多环境开发的 IDE —— CEC-IDE 微软已将 Python 集成到 Excel,龟叔参与架构制定 中国程序员拒写赌博程序被拔 14 颗牙,全身损伤达 88% 朱雀仿宋 —— 首款开源仿宋字体 Podman Desktop 突破 50 万下载量 自动跳过开屏广告应用「李跳跳」无限期停止更新 System Initiative 宣布将其所有软件全部开源 Unity 引擎中国版“团结引擎”正式发布 Windows QQ 客户端存在远程代码执行漏洞 小米备案 mios.cn 网站域名
{{o.name}}
{{m.name}}

猜你喜欢

转载自my.oschina.net/u/4843764/blog/8601037