小蚂蚁说:
本文是根据蚂蚁金服 Service Mesh 布道师敖小剑在 Service Mesher 社区进行的第一次 Meetup 上分享的《大规模微服务架构下的 Service Mesh 探索之路》现场演讲内容实录整理编辑而成,希望能给关注 Service Mesh 产品的朋友们带来帮助和了解。
蚂蚁金服 Service Mesh 布道师敖小剑
今天给大家带来的内容叫做 Service Mesh 探索之路,但是在前面加了一个定语:大规模微服务架构下。之所以加上这个词,是因为我们这个体系是在蚂蚁金服这样一个大的架构下进行的,蚂蚁金服的体量大家可以想象,所以这个探索会带有一个非常隆重的色彩:对性能/规模/高可用等方面的思考。
今年 6 月初,在深圳的 GIAC 大会,我们同事披露了这个正在开发中的 Service Mesh 产品,我们现在暂时命名为 SOFA Mesh。我们目前的产品都在 SOFA 品牌下,比如 SOFA RPC,SOFA Boot 等。今天我们详细介绍 SOFA Mesh 这个单独产品,上次大会只是简单披露,也就是给大家介绍说我们有这样一个产品,而我今天的内容是把这个产品详细展开。
主要是三个内容:一是 SOFA Mesh 的技术选型,二是它的架构设计,以及在最后跟大家聊一下,蚂蚁金服在 SOFA Mesh 上的开源策略。
一、技术选型
先上来一堆要求,刚才我们提到过的,因为是大规模,而蚂蚁金服的体量,大家可以想象到的。实际上在性能,稳定性上,我们的衡量标准,我们考虑的基石,都是以蚂蚁金服这样的一个规模来考虑的。
在这样一个规模下,我们会涉及到一些跟其他公司不太一样的地方,比如说:我们在性能的考量上会比较重一些。因为如果性能不高的话,可能没法支撑我们这样一个规模。在考虑性能的时候,就有另外一层考量:架构和性能之间的这个权衡和取舍是要非常谨慎的。性能要求不太高的情况下,架构可能的选择,和需要比较高性能的情况下,可能会有完全不一样的取舍。稳定性就不必说了。
部署方面的要求,首先是我们会用于多种场合:
主站是指我们蚂蚁金服内部,比如大家用的最多的支付宝。
金融云,可能有一部分和我们有联系的同学会有所了解,这个是我们推出的针对金融行业的云。
然后还有我们的外部客户
部署上会要求这三个场合都能使用。
部署环境也会有多种,刚才我们调查到,有部分同学相对比较前沿一些,现在就已经上 k8s 了。有部分同学还是停留在以前的虚拟机以及物理机这种状态,也有一部分自己上了容器,还有部分同学可能会使用不同的公有云和私有云。这几种不同的环境,我们都是需要满足的。
第三点可能要特殊一些,需要满足各种体系。刚才我们在调查的时候了解到,有部分同学是在做旧有系统改造,那在改造的时候就会遇到一个问题:除了 Service Mesh 之外,还需要跟原来的体系,比如说 SOFA,或者社区主流框架如 Dubbo,Spring Cloud,相互之间打通和过渡。怎么在技术转型期间平滑的让业务做变更,是我们在整个技术选型之前提出的实际要求。整个技术选型是在这样一个背景下进行的。
我们做技术选型的时候,有两大方向:
一个选择是在开源产品上做
我们先看右边的路线,起点是找一个开源产品,fork 出来,做增强/扩展/定制,和内部集成。因为开源产品还在继续往前走,所以我们会持续做版本更新,也可以从社区拿到最新版本。相当于是从开源社区做获取,然后接下来做反馈,让我们的一些产品,我们做的东西反馈回去。
这条路线比较大的好处是从一开始就可以得到社区的支持,社区往前走的时候也跟着往前走。如果做的比较好,愿意让自己的产品反哺社区,那么社区也可以从中受益。
当然这里面有一个小问题,就是说可能我们自己这个产品路线和开源产品路线可能会有一些分歧,可能我们领先一步,也可能他们领先一步,或者一个事情可能有两个做法。这种情况下,如何让社区的接受我们的改动,会变成这条路线上比较头疼的一个问题。
这是两条路线上的第一条,选择以开源产品为起点。
另外一种思路全新打造
或者,如果手上已经有一套类库或者框架,可以在这个基础上做包装。
这条路线有一个好处,可控性比较强。因为整个体系是全新打造或者在原有体系上演进而来的,整套体系基本上都是自己的开发团队完全可控的。
这条路线会遇到一个问题,因为长期上看我们也是希望开源的,而开源就意味着不能将自己内部太多的定制化的东西直接做进去,所以在架构上需要考虑可扩展性,可以定制化。因为开源出去的应该是一个标准产品,这样的产品才可以得到社区和客户的认可。客户希望看到一个干净的东西,也需要做扩展,整个体系在设计上会有所不同。
两条路线的终点,从图上看,我们有两个目标:
第一个目标是内部落地
前面提到的,我们需要在蚂蚁金服主站这样的一个巨大规模的场景下落地,这是蚂蚁金服自身的需求。
第二个目标是技术输出
因为蚂蚁金服在公司策略上有科技输出的内容,不仅仅我们自己用,我们还需要给出去。
现在我们来看这个问题:目标在这里,然后有左右两条路线,我们该怎么选择?在做的技术选型的时候,这是一个非常大的分歧点,到底是从左边走,还是从右边走?
在公布结果之前,我们先来看一下有什么可选方案。
这是开源方案的选择,第一代的 Service Mesh。
左边的 Linkerd,这个基本上,目前看,大家都已经有点嫌弃了。因为它没有控制平面,用 Scala 写的,基于 JVM,资源消耗比较大。它的可扩展性比较有限的,相对于 Envoy 的扩展性。然后它里面有个 dtab,有接触到的同学就会有认识:dtab 的语法,非常的不人性,很难理解,使用不太方便。另外它的功能是远远不够的,对于蚂蚁金服来说。另外这个产品本身的发展前景已经很暗淡了,所以这个选项就被淘汰了。
Envoy 是非常不错的,做了一些令我们意外的事情:安心的去做好数据平面,没有往上面做很多的东西,而是创造性的提出了 XDS API。整个设计是非常优秀的,性能和稳定性也表现得非常好,甚至看到业界有一个趋势,有一部分的公司开始把他们的 nginx 替换了,不再用 nginx 了,而是用 envoy。也就是说,现在它的稳定性和性能达到和 nginx 一个级别,nginx 大家应该都有听说过,envoy 已经是这样一个工业成熟度。
我们当时选型时是比较头疼的,因为它是 c++写的,c++14。和我们技术栈的差异会比较大,因为蚂蚁的技术栈是以 Java 为主,长期的话,我们可能部分转到 Golang 上去。在这种情况下,C++的技术栈,会让我们比较尴尬,也不是说我们找不到会 c++的同学,而是说,长期上会和我们的方向不一致,我们要在 Java 和 Golang 的技术栈之外再加一个 c++,这就比较难受。
然后我们内部会有大量扩展和定制化的需求。因为我们内部有我们自己的产品,我们自己的需求,我们的通讯方案,我们内部的追踪,监控,日志方案,所以工作量非常大。
总结说,我们觉得 Envoy 很好,但是我们不能简单用。但是它在数据平面上的表现我们是非常认可的,Envoy 在这点做得非常好。
开源方案里面的第二代,istio 是我们当时的第一选择,重点关注对象。Istio 现在最大的问题在于它迟迟不能发布生产可用版本,大家如果对 istio 有了解的话,会知道 istio 刚刚发布了 0.8 版本,第一个长期支持版本,但是这个版本也不是生产可用。不出意外的话,按照目前的进度,istio 应该会在 7 月份发布它的 1.0 版本,但是从我们目前的感受上看,1.0 估计可能还是不能工业级的使用。所以需要等,而我们没法等,但是 Istio 的理念和方向我们非常认可。大家看一看,我们这个技术选型有多纠结。
右边的 Conduit,现在 Conduit 的最大限制是它只支持 k8s。而现在蚂蚁金服还没有普及 k8s,我们现在还有很多系统是跑在非 k8s 上的。第二是它的数据平面是 Rust 编写的,这个语言更加小众了,在座的同学有没有人了解 Rust 这门语言?或者听过。(备注:现场大概十几个人举手)大概 10%左右的同学听过。好,Rust 语言排名大概在 50 名左右。这个语言本身还是蛮认可的,我还很喜欢这个语言,它的一些特性还是非常有道理,如果掌握好还是可以写出非常好的产品,但是它的入门台阶会比较高一点。这个地方比较讨厌的事情是说,因为这个语言本身比较小众,所以基本上是没办法从社区借力的。这里可以举个例子,大家可以看一下 Conduit 的 committer 的人数,大概是 25 个左右,还包括像我这种只提交了几行代码的。Conduit 从 12 月份开源到现在已经有半年时间,半年时间只有这么多的 committer,其中真正有贡献大概 9 到 10 个人,基本上都是他自己的员工。也就说这个产品基本上没办法从社区借力,一个产品,如果大家一起来帮忙,其实很多的细节是可以完善的,但是 Conduit 就卡在 Rust 语言上。
然后还是同样有技术栈的问题,因为这个原因,基本上 Conduit 我们也没法用了。
我们再看一下国内的在 Service Mesh 领域,其他的一些比较前卫的同学,他们的选择会是什么?
首先是华为,华为自己做了一套 Golang 版本,名字叫做 Mesher。这是由他们之前的一套类库演进而来。它走的路线是,先有类库和框架,然后加 proxy,proxy 打通了之后再慢慢的开始添加控制平面。这是一条非常非常标准的路线,我这边给一个词叫做老成持重,因为这条路是最安全的:每一步都是基于现有的产品,很快就可以到下一个里程碑,然后每个里程碑都可以解决一些实际问题,可以直接得到一些红利,这个方案是比较比较稳妥的。比如说第一步是把 proxy 做进去,有了这个切入口之后,就在第一时间获取跨语言的红利,还有技术栈下沉的好处。然后控制平面的创新,可以在这个基础上慢慢往前做。
在对接 Istio 这一条上,现在华为的策略,我们现在从公开途径了解到的是:部分对接 istio,也就是有一部分的 API 兼容 Istio。但是细节上还不太清楚,因为它的开源还没出来,目前得到的消息是,会在 7 月份开源。
第二个是新浪微博的 Motan Mesh,他们也是 Golang 的,但他不太一样,是全新实现。他们用 Go 语言重新写了一把,主要原因是因为它没有 golang 类库,Motan 是基于 Java 的。
刚才看到的这两个产品,他们的思路大体上是相同的,差异在哪里?就是启动的时候是用已有的类库还是重新写?这两个选择之间最大的麻烦在于编程语言,华为原来有 go 的类库,所以继续用 golang 包装一下就好了。但是新浪的类库用的是 Java,而 sidecar 选择的是 go 语言,所以只能重新做了。
我们再看腾讯,最近看到他们有类似的产品出来。我们看看他们的资料:在数据平台上继续选择 Envoy,因为它比较成熟。腾讯的话大家比较熟悉,尤其是腾讯有非常深厚的 c++背景,所以 Envoy 对他们来说,技术栈是非常 OK 的。而且之前内部其他领域 Envoy 也是在用的,所以底层非常自然的选择了 Envoy。然后控制平面上,据传是"挣扎了一下"。这个词是我抄过的,“他们挣扎了一下”,最后还是选了 Istio。然后自己做定制和扩展,然后注意到他们也解耦了 k8s。这也是其中一个关键的点:要不要绑定 k8s?
这里还有 UCloud 的一个很有意思的做法,另辟蹊径啊。他的方案很有意思,是一个轻量级的实践:从 Istio 里面,将 Envoy 和 Pilot 单独剥离出来。就是说不用 Istio 整体,把 Mixer 和 Auth 的模块去掉,只要最重要的 Envoy,然后把 Pilot 剥离出来。然后这个 Pilot 还是个定制版,把其他的 adapter 干掉了。Pilot 主要是做服务发现,它底层用 ETCD,做了一个 ETCD 的 adapter,把其他的 adapter 从 Pilot 中去掉。做完这几个事情之后,整个体系就可以脱离 k8s 了,这是一个比较有意思的实践。
总结:在讲我们技术决策过程之前,我们过了一下目前市场上的主要产品,以及一部分实践者的做法。
我们现在来详细讲一下,SOFA Mesh 在技术选型上的考虑。
首先第一个,数据平台上 Envoy 是最符合我们要求的,Envoy 确实好。第二个事情是 Envoy 提出的 XDS API 设计是非常令人称道的,我们现在对这个的评价是非常高的。它实际上是一套通用的 API,由于时间的缘故,我今天就不在现场展开 API 的细节。只能说 XDS API 基本上已经成为数据平面和控制平面之间的一个事实标准。
在这种情况下,我们其实是想用 Envoy 的,但是刚才提到我们有个技术栈选择的问题:我们不愿意将 c++纳入到我们主流的技术栈。然后我们本身有太多的扩展和定制,逼得我们不得不去改 Envoy,我们不能简单的拿过去用,我们需要做很多扩展的。
另外一个事情是,我们这个 proxy 不仅仅是用于 Mesh,我们有可能把它引入到 API Gateway 里头,以及后面会提到的名为 Edge Sidecar 的模块。因为这个原因,所以,怎么说呢,想用,但是不合适用。
第二就是在 Istio 上,控制平面这一块 Istio 可以说是做的最好的。基本上,到目前为止,在控制平面上,暂时我们还没有看到做的比 Istio 更好的产品,或者说思路。目前 Istio 整个设计理念,包括它的产品方向,也是我们非常认可的。
但是 Istio 的性能是目前最大的问题,而我们有一个重要的前提:大规模应用。要用在蚂蚁金服主站这样一个场景下,性能和稳定性对我们非常非常的重要。第二个问题是它对非 k8s 的支持不够理想,因为我们还涉及到一个 k8s 没有完全上线的问题。第三个是和侵入式框架互通的问题,我们内部用的是 SOFA,对外推出的时候我们的客户用的可能是 Dubbo 或者 Spring Cloud,Mesh 上去之后,两个系统现在走不通,这是大问题。
最终我们的策略是这样的,这是我们 SOFA Mesh 的技术选型:左边是 Istio 现有的架构,Envoy/Pilot/Mixer/Auth,右边是我们 SOFA Mesh 的架构。
最重要的第一点:我们用 Golang 开发的 Sidecar 替换 Envoy,用 Golang 重写整个数据平面。
第二点是我们会合并一部分的 Mixer 内容进到 Sidecar,也就是 Mixer 的一部分功能会直接做进 Sidecar。
第三点是我们的 Pilot 和 Auth 会做扩展和增强。
这是我们整个的技术选型方案,实际上是 Istio 的一个增强和扩展版本,我们会在整个 Istio 的大框架下去做这个事情,但是会做一些调整。
二、架构设计
然后我们来详细介绍一下在这个技术选型上我们怎么去做实现。
首先是 Golang 版本的 Sidecar,我们会参考 Envoy,非常明确的实现 XDS API。因为 XDS API 是目前的事实标准,所以我们选择遵循,然后我们会让它兼容 Istio。
在协议支持上,我们会支持标准的 HTTP/1.1 和 HTTP/2,也就是大家常见的 REST 和 gRPC 协议。然后我们会增加一些特殊的协议扩展,包括 SOFA 协议,Dubbo 协议,HSF 协议。我们现在正在做这几个协议的扩展,然后 XDS API 我们支持,mixer service 我们没有改动,遵循现有实现。
最大的变化在 Mixer,其实刚才的 Sidecar 虽然是全新编写,但是说白了是做 Envoy 的替换,在架构上没有什么变化。但是第二步的变化就非常大,我们会合并一部分的 Mixer 功能。
Mixer 的三大功能:
1.check。也叫 precondition,前置条件检查,比如说黑白名单,权限。
2.quota。比如说访问次数之类。
3.report。比如说日志,度量等。
三大功能里面,注意到,前两个功能是同步阻塞的,就是一定要检查通过,或者是说 quota 验证 OK,才能往下走。如果结果没回来只能等,因为这是业务逻辑,必须要等。而 Report 是可以通过异步和批量的方式来做的。
在这里,我们现在的决策是:我们会将其中的两个部分(check 和 quota)合并进来,原有 report 部分我们会继续保留在 mixer 里面。
可能大家会问:为什么我们要选择用这个方案,而不是遵循 Istio 的标准做法?我们之前聊到,我们会尽量去和 Istio 做兼容,跟随 Istio 的设计理念和产品方向,但是我们在它的架构上做了一个重大的调整。为什么?
最大的问题就是对性能的影响。
给大家解释一下,看右边这个图,Envoy 在每次请求进来的时候,要去做两次调用:
1.第一次在请求转发之前要做一次 check,这个 check 里面包含了 quota。Check 完成通过,才能把请求转发过去。
2.请求转发完成之后,再调用 report,报告一下响应时间,日志,度量等信息
每次 traffic 都会有两次调用:一次 check,一次 report。而这是远程调用,因为这两个模块是两个进程,Mixer 是单独部署的。
同步阻塞意味着必须要等,远程调用意味着有开销而且有延迟。这个事情是发生在每一次请求里面,意味着整个的性能一定会受影响。而考虑到我们蚂蚁金服这样一个体量,其实我们是很难承受。所以我们有自己的观点:我们不是太认可这样的一个方式,我们的想法是说我们要把它拆分出来想一想:
如果是需要请求做同步阻塞的功能,比如说黑白名单的验证,可能要检查 IP 地址,可能检查 quota。这些逼请求一定要做同步阻塞等待结果的功能,就不应该放在 Mixer 中去完成去远程调用,而应该在 Sidecar 中完成。
这是我们的观点,原因就是远程调用带来的系统开销,这个代价实在是太高了!
然后其他的功能,比如说可以优化为异步的,或者可以以批量方式来提交的,最典型的就是 Report。Report 其实是可以异步提交,可以把十个请求打包到一个 report 同时提交,这些都是 OK 的。
这是我们的基本想法。
这个问题其实在 Istio 里面是给了一个解决方案的。最早的时候,Istio 0.1 版本中,一出来就发现这个问题。从去年 5 月份开始到现在,13 个月的时间里,他只给了一个解决方案,就是在 Mixer 上的这个位置加了一个 Cache。这个的 Cache 的想法是:把这些结果缓存在 Envoy 的内存里面,如果下次的检查参数是相同的,那我们可以根据这样一个缓冲的设计,拿到已经缓存的结果,就可以避免远程调用。这个方式是很理想的,对吧?只要缓存能够命中,那就可以避免这一次远程调用。
然后第二个优化是 report,现在的 report 是通过异步模式完成的,而且是批量。
理论上说,如果这两个事情做到足够理想,Mixer 应该就不是瓶颈。对吧?
问题在于:这个 Cache 真的搞得定吗?
我们给一个简单的例子,我现在假设 Mixer 有三个 adapter。然后它的输入值是不同的属性,属性是 istio 的概念,理解为若干个输入值。假设,需要三个 adapter 分别检查 A/B/C。如果这三个属性 A/B/C,他们只有 100 个取值范围,每个都是从 0 到 100,我们假设这种最简单的场景。
如果这三个 adapter 分别做缓存的话,需要多少个缓存项?很容易计算吧?100 个 a,100 个 b,100 个 c,非常容易计算,这种情况下,其实就是 a+b+c 等于 300 嘛。理解一下:有三个输入,每个输入只有一百个取值范围,我们要把他们缓存起来。这些缓存大小,就是允许的范围,然后加起来。只要有 300 个 key,就都可以缓存起来。
但是,这个方法中,缓存是做在 mixer 这边,每个 adapter 单独缓存。但是,在 Istio 中,缓存是做在 Envoy 这端的,因为做在 mixer 这端是没有用的,还是要远程调用过去。它做缓存的很重要的目标是要在客户端避免远程调用。所以,这种情况下,把缓存放到这里(备注,图中绿色方块)。
大家现在想一想,现在这里只有一个缓存,只有一个 key/value。现在还有刚才的这个场景,A/B/C 各自的取值范围都是一百。但是现在缓存放在这边的话,实际上的这个 key 要考虑三个值了,A/B/C 的组合。这种情况下,它的最大缓存个数是多少?
(备注:现场回答,a 乘 b 乘 c)
a * b * c?还能 a + b + c 吗?做不到了,对不对?现在是 a * b * c,从 300 变成这么大的数了。为什么?因为缓存是在这个地方做的,根本没有办法像这样分开做,所以这里就变成了一个笛卡尔乘积。
这个笛卡尔乘积有一个很大的麻烦,也就是说,如果 adapter 检查的某个属性,它的取值范围比较大,比如说要检查客户端的 IP 地址?你想想,这个 IP 地址有多少个取值范围?数以几十万几百万计,对吧?这种情况,哪怕在前面再乘以特别小的值,哪怕只是十,二十,如果是加 20 根本没所谓的,加 200,加 2000 都没所谓的,那乘个 200,乘个 2000 试一下?瞬间就被干掉。IP 地址可能只是百万级别,再在前面乘个 100,乘个 1000,瞬间就疯掉了。这个 key 值基本上已经是大到不能接受:要么就全放内存,内存爆掉;要不然限制缓存大小,就放 1 万个,缓存的命中率会非常低,整个缓存相当于失效了。
这个细节,因为时间原因,不在这里详细讲了。
这里讲第二点,我们的反省:隔离怎么做?
Mixer 有一个基本的设计目标,就是希望提供一个统一的抽象(就是这个 adapter 的概念),用它来隔离基础设施后端和 Istio 的其他部分。但是在这个点上我们的反思是:我们认可这样一个隔离。大家理解基础设施后端的概念吧?举个例子,日志处理如 prometheus,各种后端监控系统。这些系统和应用之间,我们认为这种情况下的确应该做隔离,没必要每个应用都去和基础设施后端产生直接的联系。这个观点是我们是赞许的。
但是我们现在的意见是,我们把这条线(备注:连接应用和基础设施后端的标记有红叉的线)从应用里面拿下来之后,我们把它下沉。下沉到 Sidecar,够不够?Istio 的做法是,它觉得这个地方应该再往前走一步,到 Mixer 里面。由 Mixer 去完成和基础设施后端的连接,走这根线(备注:图中连接 Mixer 和基础设施后端的线)。但是多了这样一个隔离之后的代价,就是在中间的这根红线上,会多一次远程调用。
现在只有两个选择:和基础设施怎么连?这条线(备注:最左边的)大家都认为没必要,这两条线(备注:中间和右边的线)之间选,两条线的差异,就是要付出一次远程调用的代价。
继续反省:什么是基础设施后端?
这里我们做一个列表,整个 Istio 现有的 adapter,大家可以看到,大概是这些。前面这两个部分是实现 check 和 quota 的 adapter,后面这些 adapter 是实现 report 功能。
在这里,我们的反省是:这些功能,比如说黑白名单,比如说基于内存的 quota,或者基于外部 redis 的 quota。我们认为这些功能不太应该视为后端基础设施,因为这些功能更应该是说是体系内置的基本能力,应该直接把它们做成 Mesh 的内置产品,或者说可以做标准化,然后和外部系统集成。这些我认为应该是 Mesh 的最基础的功能,比如说我们 SOFA Mesh 可以提供基于 Redis 的 quota 方案,直接就把这个功能给出来了。我不认为应该再去跟外界的一个所谓的基础设施后端发生联系。
但是下面这些我们是觉得 OK 的。这些 adapter 大家有概念吧,prometheus 大家应该都接触过的。剩下的这些在国内可能用的不多,是各种日志和 metric 相关的功能。把这些视为基础设施后端,我们是非常理解的。包括我们内部,我们蚂蚁也有很多这样的系统,相信各位自家的监控方案也是不一样的。
这些视为基础设施,和系统隔离开,我们认为这是非常有必要,可以理解,可以接受。
这是我们在这一点(备注:何为基础设施后端)上和 istio 的差异。
因为时间原因,我们就不再深入去讲,这里我给了一些我博客上的文章。前段时间,我们在做技术选型,在做前面整个架构设计时,在这一点上有些讨论。以及我们最重要的决策:为什么要把 Mixer 合并进去。细节都在这几篇文章里面,大家如果有兴趣,可以去详细了解。
备注链接地址(请复制网址到浏览器打开):
Service Mesh 架构反思:数据平面和控制平面的界线该如何划定?
https:// skyao. io/post/201804-servicemesh-architecture-introspection/
Mixer Cache: Istio 的阿克琉斯之踵
https:// skyao. io/post/201804-istio-achilles-heel/
Istio Mixer Cache 工作原理与源码分析(1)-基本概念
https:// skyao. io/post/201804-istio-mixer-cache-concepts/
Istio Mixer Cache 工作原理与源码分析(2)-工作原理
https:// skyao. io/post/201806-istio-mixer-cache-principle/
Istio Mixer Cache 工作原理与源码分析(3)-主流程
https:// skyao. io/post/201806-istio-mixer-cache-main/
Istio Mixer Cache 工作原理与源码分析(4)-签名
https:// skyao. io/post/201806-istio-mixer-cache-signature/
我们还有一部分现在没有合并进来的 adapter 和 mixer,report 的这部分。但是这块不是说完全没有问题,我们现在有一个担心,report 这块可能会存在一个叫做网络集中的问题。比如说,大家会注意到,应用和 Sidecar 是一对一部署的,有一万个应用,就有一万个 Sidecar。基础设施后端也是多机部署的。
而现在的方式,流量会先打到 Mixer 来,Mixer 也是高可用的,也是会部署多台。但是这个数量肯定不是一万这个级别,跟这个肯定会有很大的差异。这样流量会先集中,通道会突然间收缩一下。总的流量没变,但是通道的口径要小很多。
对网络吞吐量也会有影响。比如最简单的,如果应用直连,走交换机直接就过去了。
如果是 Sidecar 模式,是在这个位置上(备注:应用和 sidecar 之间的绿色连线)加一个远程调用,但是应用和 Sidecar 之间走的是 localhost,localhost 根本就不走网卡,直接环回地址就走了。对性能不会有什么影响,对网络流量的影响就为零了。所以这两个方案相比,吞吐量不会有变化。
但是,如果在 Sidecar 和 Backend 之间再加一个 Mixer,这意味着要走两次网络,这样的话会有一个流量翻倍的问题。
所以这个地方可能会带来一些问题,但暂时我们现在还没做决策,我们现在还不是很确定这个问题会不会导致质的影响。所以我们现在暂时还是把它放在这里,就是说我们后面会做验证,如果在我们的网络方案下,这个方式有问题的话,我们可能再合进去。但是如果没问题的话,我们认为分开之后架构确实会更理想一些,所以我们现在暂时先不合并。
给大家一些参考,目前 Conduit 最新版本已经把 report 的功能合并进来,然后 check 的功能,会在后续的计划中合并。我们在国内做一些技术交流,华为新浪微博他们现在通通都是选择在 Sidecar 里面实现功能,不走 mixer。
这是我们称之为梦幻级别的服务注册和治理中心,我们对他的要求是比较多的:
我们需要他支持跨集群,比如说我们现在有多个注册中心,多个注册中心之间可以相互同步信息,然后可以做跨注册中心的调用
还有支持异构,注册中心可能是不一样的东西。能理解吧,有些是 Service Mesh 的注册中心,比如 Istio 的,有些是 Spring Cloud 的注册中心,比如 Consul。
然后终极形态,我们希望在两种场景都可以支持。
右边的这个图,是我们构想中的比较理想化的注册中心的架构,我们会有各种 adapter 实现,会有一个抽象的模型,把他们抽象起来,然后有一些接口。后来,在我们实现的时候发现,Istio 的路线跟我们有点像,Istio 本身也是做了跨平台的 Adapter,也做了一层抽象,然后它也提出了一些 API。所以我们最终的决策是:往 Pilot 靠。
我们以 Istio 的 Pilot 模块为基础去做扩展和增强:
增加 SOFA Registry 的 Adapter,SOFA Registry 是我们内部的服务注册中心,提供超大规模的服务注册和服务发现的解决方案。所谓超大规模,大家能理解吧?服务数以万计。
再加一个数据同步的模块,来实现多个服务注册中心之间的数据交换。
然后第三点就是希望加一个 Open Service Registry API,增加服务注册,因为现在 Istio 的方案只有服务发现,它的服务注册是走 k8s 的,用的是 k8s 的自动服务注册。如果想脱离 k8s 环境,就要提供服务注册的方案。在服务发现和服务模型已经标准化的情况下,我们希望服务注册的 API 也能标准化。
这里还有一个比较特殊的产品,因为时间限制,给大家简单了解一下。
我们计划的 Edge Sidecar 这个产品,它是东西向服务间通讯的一个特殊桥梁。所谓东西向,大家能理解吧?东西向指服务间通讯,也就是 A 服务调用 B 服务。对应的还有南北向,南北向通常是指从外部网络进来调用服务,如走 API Gateway 调用服务。在东西向通讯中,我们有时会需要一个比较特殊的途径,比如说在这个图中,我们有两个集群,两个集群各有各自的服务注册中心。我们通过增强 Pilot 的方式打通两个注册中心,可以知道对方有什么服务。
当 A 服务发出一个请求去调用 B 服务的时候,由于两个集群是隔离的,网络无法相通,肯定直接调用不到的。这时 local sidecar 会发现,服务 B 不在本集群,而在右边这个集群里,Local Sidecar 就会将请求转发给 Edge Sidecar,然后由 Edge Sidecar 接力完成后续的工作。
这个模块的功能会比较特殊一点,因为时间限制,在今天的过程当中,Pilot 和 Edge Sidecar 就不再详细展开。
三、开源策略
SOFA Mesh 的开源策略,可能会和大家之前接触到的一些开源产品,有质的差异,非常的不一样。
备注:这块就不整理了,直接看图中文字。
这是整个大的愿景。
SOFA Mesh 的开源态度,其实我写左边这些的时候是有很大压力的。用官方话语说,不针对任何人和任何项目,我们不影射任何人。
但是,大家如果经常用各种开源产品的话,会发现一些问题。比如说,开源的时机。大家接触的开源产品,尤其是国内的,不管是多大的公司,通常都是产品完成之后,甚至是使用好多年。好处是相对稳,缺点是什么?(备注:现场回答,老)对,技术可能已经很老了,十年前的!还有可能是它都已经放弃了,开源出来时自己不再使用。或者说是一个很新的产品,真的很新,他自己不用,说就是做出来给你用的。(备注:现场哄笑)自己不用的产品给你用,你的第一反应是什么?小白鼠是吗?你愿意做小白鼠吗?你敢把公司的这个产品放上面吗?
SOFA Mesh 这次比较特殊,非常非常特殊。我们这个产品,会在非常早的时间点上开源给大家。我甚至可以跟大家说,其实在这个点上,我们更重要的是摆明态度:我们要开源,我们要把这个产品开源给大家,甚至早到我们自己都不认为这是一个完整的产品。为什么?
有几个事情,这几点大家认可吧?业界最新的技术,Mesh 是最新技术大家都已经达成共识了吧?业界最好的架构,当然这个我们还在努力中,尽量做好。然后我们会给大家一个承诺,大家不用担心做小白鼠,你能拿到的产品,我们已经趟过一遍了。
开源动机,这个地方我们也不说大话,就是我们希望能吸引整个社区,谋求这样一个合作,走开源共建的方式。这是为什么我们会选择在现在这个时间点上开源出来。
整个产品的维护,什么样的产品会让你有信心,不用担心中间断掉?最重要的一点是我们自己在用。想想,如果支付宝在用,你担心这个项目死掉吗?对不对?如果这个产品本身是蚂蚁金服这样级别的公司,在它的线上将会使用的产品,而且是同样一个核心的版本。相信在这种情况下,大家就放心了吧?
SOFA Mesh 的合作模式,我称之为"多层次全方位开放"。
中间这幅图,最底下的是基础类库,实现各种功能。我们希望有这样一套基础类库,类比 Netflix 的 OSS 套件。因为 Golang 的类库做的不是很好,没有 Java 沉淀的那么好。目标是希望在这个产品做完之后,能给整个社区沉淀出一套 Golang 的微服务基础类库。最重要的一点,是希望最好能大家合力,在这个点上做出一套成熟稳定性能足够好的产品。这是在类库层面。
在类库之上,功能模块层面,比如说 Golang 版本的 Sidecar,我们希望它能替换 Envoy 的功能。在原来使用 Envoy 的情况下可以使用这个 Sidecar 来替代。体现在什么层次?就是说,如果想用 Envoy,也很喜欢它,但是可能又受限于 C++语言栈,更希望是 Golang 语言栈的时候,可以选择我们这一套。或者如果我们抱有同样的想法,比如想把 Mixer 合进来,可以在 Sidecar 这个层面上来重用我们的产品,跟我们做合作。或者我们刚才提到的这个产品,增强版本的 Pilot,大家有印象吧?我们会实现一个非常强大的,跨各种集群,各种异构的服务注册机制。然后是 Edge Sidecar,在两个不同的区域之间,比如两个不同的机房,IP 地址不通的情况下,帮你打通服务间调用。这些功能模块,会以单独的产品和项目出现,你可以在某一个产品上跟我们合作。
第三点就是完整的产品,如果你需要一个完整的 Service Mesh 的产品,把这些所有的功能都包括进来,没问题,SOFA Mesh 可以拿来用。
有些同学可能会需要更完整的解决方案,我们的金融云会提供 SOFA Mesh 的支持,这是我们的目标。你可以将你的系统,架构在金融云之上。
今天的几位讲师来自不同的公司,我们非常欢迎业界参与。如果大家有意在 Service Mesh 领域做一些事情,大家可以相互之间做技术的沟通,技术的交流,在社区合作上做一些事情。
有些同学说,我只是用一下,好像没法做什么贡献。其实,"用"是一个很重要的合作,你能够用,你就会遇到问题,有你的诉求,遇到什么样的 bug,有什么样需求没有满足。这些对我们来说,是非常重要的输入。在这一点上,欢迎和我们保持合作。
SOFA Mesh 的开源宣言,写的比较狗血。但是在这一点上,我觉得这一次 SOFA Mesh 在开源上还是做的比较有诚意。
首先我们认可这个大方向,我们看好 Service Mesh 的前景。体现在什么上呢?我们现在规划,未来整个蚂蚁金服内部的大部分应用都会逐渐的往 Service Mesh 上落。这个内部已经达成一致了,会往这个方向走。
第二是说,“勇敢探索”,“耐心填坑”,有在 1.0 版本之前用过大型开源产品的同学,对这两个词都应该有深刻体验,对吧?包括前两年用 0.*版本和 1.1/1.2 版本的 k8s 的同学。任何一个新的技术,一个大的方案出来,前期的时候,这些事情是一定会遇到的。但是我们觉得还是要去趟这个事情。
我们要继续推进这样一个技术进步,包括 Service Mesh 技术社区的推广。大家如果有注意的话说,Service Mesh 技术社区已经重新启动了,我们在跟很多的公司,包括甚至我们一些竞争对手合作。从技术进步的角度说,我们欢迎大家在一个公平的基础上做技术交流。
然后我们是愿意做分享的,整个产品,我们接下来所有能开源的东西都会开源出来。除了一些内部定制化的东西,内部没有开源的产品的集成。基本上,你们能看到的东西,也就是我们内部用的东西。
我们寻求和大家的合作,包括刚才讲过的各个层面的合作,哪怕是简单的使用,发现问题给我们提交一些 bug,也是非常好的合作契机。
这里我喊一个口号,这个口号有点大,“集结中国力量,共建开源精品”。这里面有个词,比较大一点,我也斟酌了一下,中国这两个字敢不敢用。最后我觉得还是用吧,至少到目前为止,Service Mesh 这个技术领域,在全世界目前都还没有成熟的场景落地的情况下,我们目前在这方面的探索,已经是走在最前面的了。
在这一点上,我们是希望能联合国内在这个领域做探索的同学,我们一起来做这个事情。我们开源的一个重要目的,是说不管大家在商业上有什么样的竞争,至少在技术领域上,包括刚才说的可以在类库层面,产品层面,或者社区合作方面,开展合作。我们希望能够尽可能的联合国内的合作伙伴,包括竞争对手一起来营造整个技术氛围,把整个 Service Mesh 技术体系的基本水准提升上来。
这一点应该是大家比较关注的,什么时候开源? 我们只能告诉大家说,on the way,正在路上。
本来这一页的写法应该是贴个地址给大家的,但是因为进度的原因还没有实现,有可能会在一到两个星期之后,在 7 月份的时候开源给大家。
需要澄清的一点,大家的期望值不要太高,因为我们开源出来的第一个版本,主要是释放姿态,把我们的开源共建的姿态释放出来。我们的第一个版本,肯定不是一个完善的版本。(备注:现场有同学问,有在用吗?)内部有用一部分,Sidecar 内部已经在用了,但是第二部分的内容,比如说 XDS API 的集成,我们现在正在做。我们不希望等把产品做完善了,比如说两年之后非常成熟的情况下再来开源。我们希望尽可能早的开源。
(备注:现场提问,7 月份的版本,不一定是生产环境可用?)对,是的。有一部分功能是生产可用的,有一部分功能不是,因为我们是迭代上去的。
本文转载自公众号蚂蚁金服科技(ID:Ant-Techfin)。
原文链接:
https://mp.weixin.qq.com/s/JQ0PPAsO6qiAW-q-rI-Bsg
评论