Service Mesh深度解析

本片文章不是原创,转自:https://time.geekbang.org/art...php

微服务方兴未艾如火如荼之际,在 spring cloud 等经典框架以外,Service Mesh 技术正在悄然兴起。到底什么是 Service Mesh,它的出现能带来什么,又能改变什么?本文整理自数人云资深架构师敖小剑在 QCon 2017 上海站上的演讲。
简单回顾一下过去三年微服务的发展历程。在过去三年当中,微服务成为咱们的业界技术热点,咱们看到大量的互联网公司都在作微服务架构的落地。也有不少传统企业在作互联网技术转型,基本上仍是以微服务和容器为核心。
在这个技术转型中,咱们发现有一个大的趋势,伴随着微服务的大潮,Spring Cloud 微服务开发框架很是普及。而今天讲的内容在 Spring Cloud 以外,咱们发现最近新一代的微服务开发技术正在悄然兴起,就是今天要给你们带来的 Service Mesh/ 服务网格。

我作一个小小的现场调查,今天在座的各位,有没有以前了解过服务网格的,请举手。(备注:调查结果,现场数百人仅有 3 我的举手) 既然你们都不了解,那我来给你们介绍。首先,什么是 Service Mesh?而后给你们讲一下 Service Mesh 的演进历程,以及为何选择 Service Mesh 以及为何我将它称之为 下一代的微服务,这是咱们今天的内容。java

什么是 Service Mesh?

咱们首先说一下 Service Mesh 这个词,这确实是一个很是很是新的名词,像刚才调查的,大部分的同窗都没听过。node

clipboard.png

这个词最先使用由开发 Linkerd 的 Buoyant 公司提出,并在内部使用。2016 年 9 月 29 日第一次公开使用这个术语。2017 年的时候随着 Linkerd 的传入,Service Mesh 进入国内技术社区的视野。最先翻译为“服务啮合层”,这个词比较拗口。用了几个月以后改为了服务网格。后面我会给你们介绍为何叫网格。nginx

clipboard.png

先看一下 Service Mesh 的定义,这个定义是由 Linkerd 的 CEO William 给出来的。Linkerd 是业界第一个 Service Mesh,也是他们创造了 Service Mesh 这个词汇的,因此这个定义比较官方和权威。
咱们看一下中文翻译,首先服务网格是一个基础设施层,功能在于处理服务间通讯,职责是负责实现请求的可靠传递。在实践中,服务网格一般实现为轻量级网络代理,一般与应用程序部署在一块儿,可是对应用程序透明。
这个定义直接看文字你们可能会以为比较空洞,不太容易理解究竟是什么。咱们来看点具体的东西。c++

clipboard.png

Service Mesh 的部署模型,先看单个的,对于一个简单请求,做为请求发起者的客户端应用实例,会首先用简单方式将请求发送到本地的 Service Mesh 实例。这是两个独立进程,他们之间是远程调用。
Service Mesh 会完成完整的服务间调用流程,如服务发现负载均衡,最后将请求发送给目标服务。这表现为 Sidecar。git

clipboard.png

Sidecar 这个词中文翻译为边车,或者车斗,也有一个乡土气息浓重的翻译叫作边三轮。Sidecar 这个东西出现的时间挺长的,它在原有的客户端和服务端之间加多了一个代理。github

clipboard.png

多个服务调用的状况,在这个图上咱们能够看到 Service Mesh 在全部的服务的下面,这一层被称之为 服务间通信专用基础设施层。Service Mesh 会接管整个网络,把全部的请求在服务之间作转发。在这种状况下,咱们会看到上面的服务再也不负责传递请求的具体逻辑,只负责完成业务处理。服务间通信的环节就从应用里面剥离出来,呈现出一个抽象层。golang

clipboard.png

若是有大量的服务,就会表现出来网格。图中左边绿色方格是应用,右边蓝色的方框是 Service Mesh,蓝色之间的线条是表示服务之间的调用关系。Sidecar 之间的链接就会造成一个网络,这个就是服务网格名字的由来。这个时候代理体现出来的就和前面的 sidecar 不同了,造成网状。spring

clipboard.png

再来回顾前面给出的定义,你们回头看这四个关键词。首先第一个,服务网格是抽象的,其实是抽象出了一个基础设施层,在应用以外。其次,功能是实现请求的可靠传递。部署上体现为轻量级的网络代理。最后一个关键词是,对应用程序透明。
你们注意看,上面的图中,网络在这种状况下,可能不是特别明显。可是若是把左边的应用程序去掉,如今只呈现出来 Service Mesh 和他们之间的调用,这个时候关系就会特别清晰,就是一个完整的网络。这是 Service Mesh 定义当中一个很是重要的关键点,和 Sidecar 不相同的地方:再也不将代理视为单独的组件,而是强调由这些代理链接而造成的网络。在 Service Mesh 里面很是强调代理链接组成的网络,而不像 sidecar 那样看待个体。
如今咱们基本上把 Service Mesh 的定义介绍清楚了,你们应该能够大概了解什么是 Service Mesh 了。
Service Mesh 演进历程
第二个部分和你们追溯一下 Service Mesh 的演进历程。要注意,虽然 Service Mesh 这个词汇直到 2016 年 9 才有,可是它表述的东西很早之前就出现了。apache

clipboard.png

首先看“远古时代”,第一代网络计算机系统,最先的时候开发人员须要在本身的代码里处理网络通信的细节问题,好比说数据包顺序、流量控制等等,致使网络逻辑和业务逻辑混杂在一块儿,这样是不行的。接下来出现了 TCP/IP 技术,解决了流量控制问题,从右边的图上能够看到,功能其实没发生变化:全部的功能都在,代码仍是要写。可是,最重要的事情,流程控制,已经从应用程序里面抽出来了。对比左右两边的图,抽出来以后被作成了操做系统网络层的一部分,这就是 TCP/IP,这样的话应用的结构就简单了。
如今写应有,就不用考虑网卡到底怎么发。在 TCP/IP 以后,这是彻底不须要考虑的。上面说的是很是遥远的事情,大概发生在五十年前。

clipboard.png

微服务时代也面临着相似的一些东西,好比说咱们在作微服务的时候要处理一系列的比较基础的事情,好比说常见的服务注册、服务发现,在获得服务器实例以后作负载均衡,为了保护服务器要熔断 / 重试等等。这些功能全部的微服务都跑不掉,那怎么办呢?只能写代码,把全部的功能写进来。咱们发现最先的微服务又和刚才同样,应用程序里面又加上了大量的非功能性的代码。为了简化开发,咱们开始使用类库,好比说典型的 Netflix OSS 套件。在把这些事情作好之后,开发人员的编码问题就解决了:只须要写少许代码,就能够把这些功能实现。由于这个缘由,最近这些年你们看到 Java 社区 Spring Cloud 的普及程度很是快,几乎成为了微服务的代名词。
到了这个地步以后,完美了吗?固然,若是真的完美了,那我今天就不会站在这里了:)

clipboard.png

咱们看这几个被称之为痛点的东西: 内容比较多,门槛比较高。调查一下,你们学 Spring Cloud,到你能熟练掌握,而且在产品当中应用,能够解决出现的问题,须要多长时间?一个星期够不够?大部分人一个星期是不够的,大部分人须要三到六个月。由于你在真实落地时会遇到各类问题,要能本身解决的话,须要的时间是比较长的。这里是 Spring Cloud 的常见子项目,只列出了最多见的部分,其中 spring cloud netflix 下还有 netflix OSS 套件的不少内容。要真正吃透 Spring Cloud,须要把这些东西所有吃透,不然遇到问题时还会很是难受。
这么多东西,在座的各位相对来讲学习能力比较强一点,可能一个月就搞定了,可是问题是你的开发团队,尤为是业务开发团队须要多久,这是一个很要命的事情:业务团队每每有不少比较初级的同事。

clipboard.png

而后事情并不止这么简单,所谓雪上加霜,咱们还不得不面对一堆现实。
• 好比说,咱们的业务开发团队的强项是什么?最强的会是技术吗?不,一般来讲咱们的业务开发团队最强的是对业务的理解,是对整个业务体系的熟悉程度。
• 第二个事情,业务应用的核心价值是什么?咱们辛辛苦苦写了这么多的微服务,难道是为了实现微服务吗?微服务只是咱们的手段,咱们最终须要实现的是业务,这是咱们真正的目标。
可是这些还没完,比你写一个新的微服务系统更痛苦的事情,是你要对旧有的系统进行微服务改造。
全部这些加在一块儿,还不够,还要再加一条,这条更要命:业务开发团队每每业务压力很是大,时间人力永远不足。说下月上线就是下月上线,说双十一促销就不会推到双十二。老板是不会管你有没有时间学习 spring cloud 的,也不会管你的业务团队可否搞得定微服务的方方面面。业务永远看的是结果。

clipboard.png

第二个痛点,功能不够,这里列出了服务治理的常见功能。而 Spring Cloud 的治理功能是不够强大的,若是把这些功能一一应对作好,靠 Spring Cloud 直接提供的功能是远远不够的。不少功能都须要你在 Spring Cloud 的基础上本身解决。
问题是你打算投入多少时间人力资源来作这个事情。有些人说我大不了有些功能我不作了,好比灰度,直接上线好了,可是这样作代价蛮高的。

clipboard.png

第三个痛点,跨语言。微服务在刚开始面世的时候,承诺了一个很重要的特性:就是不一样的微服务能够采用本身最擅长最喜欢的最适合的编程语言来编写,这个承诺只能说有一半是 OK 的,可是另一半是不行的,是假的。由于你实现的时候,一般来讲是基于一个类库或者框架来实现的,一旦开始用具体编程语言开始编码的时候你就会发现,好像不对了。为何?左边是我从编程语言排行列表列出来的主流编程语言,排在前面的几种,你们比较熟悉. 后面还有几十种没有列出来,中间是新兴的编程语言,比较小众一点。
如今的问题在于 咱们到底要为多少种语言提供类库和框架。
这个问题很是尖锐,为了解决这个问题,一般只有两条路可选:

  1. 一种就是统一编程语言,全公司就用一种编程语言
  2. 另一个选择,是有多少种编程语言就写多少个类库

我相信在座的若是有作基础架构的同窗,就必定遇到过这个问题。

clipboard.png

可是问题还没完,框架写好了,也有可以把各个语言都写一份。可是接下来会有第四个痛点:版本升级。
你的框架不可能一开始就天衣无缝,全部功能都齐备,没有任何 BUG,分发出去以后就不再须要改动,这种理想状态不存在的。必然是 1.0、2.0、3.0 慢慢升级,功能逐渐增长,BUG 逐渐被修复。可是分发给使用者以后,使用者会不会立马升级?实际上作不到的。
这种状况下怎么办,会出现客户端和服务器端版本不一致,就要很是当心维护兼容性,而后尽可能督促你的使用者:我都是 3.0 了,你别用 1.0 了,你赶忙升级吧。可是若是若是他不升级,你就继续忍着,而后努力解决你的版本兼容性。
版本兼容性有多复杂?服务端数以百计起,客户端数以千计起,每一个的版本都有可能不一样。这是一个笛卡尔乘积。可是别忘了,还有一个前面说的编程语言的问题,你还得再乘个 N!
设想一下框架的 Java1.0 客户端访问 node.js 的 3.0 的服务器端会发生什么事情,c++ 的 2.0 客户端访问 golang 的 1.0 服务器端会如何?你想把全部的兼容性测试都作一遍吗?这种状况下你的兼容性测试须要写多少个 case,这几乎是不可能的。

clipboard.png

那怎么办?怎么解决这些问题,这是现实存在的问题,老是要面对的。
咱们来想想:

  1. 第一个是这些问题的根源在哪里:咱们作了这么多痛苦的事情,面临这么多问题,这些多艰巨的挑战,这些和服务自己有关系吗?好比写一个用户服务,对用户作 CRUD 操做,和刚才说的这些东西有一毛钱关系吗?发现有个地方不对,这些和服务自己不要紧,而是服务间的通信,这才是咱们须要解决的问题。
  2. 而后看一下咱们的目标是什么。咱们前面全部的努力,其实都是为了保证将客户端发出的业务请求,发去一个正确的地方。什么是正确的地方?好比说有版本上的差别,应该去 2.0 版本,仍是去 1.0 版本,须要用什么样的负载均衡,要不要作灰度。最终这些考虑,都是让请求去一个你须要的正确的地方。
  3. 第三个,事情的本质。整个过程中,这个请求是历来不发生更改的。好比咱们前面说的用户服务,对用户作 CRUD,无论请求怎么走,业务语义不会发生变化。这是事情的本质,是不发生变化的东西。
  4. 这个问题具备一个高度的普适性:全部的语言,全部的框架,全部的组织,这些问题对于任何一个微服务都是相同的。

讲到这里,你们应该有感受了:这个问题是否是和哪一个问题特别像?

clipboard.png

五十年前的前辈们,他们要解决的问题是什么?为何会出现 TCP,TCP 解决了什么问题?又是怎么解决的?
TCP 解决的问题和这个很像,都是要将请求发去一个正确的地方。全部的网络通信,只要用到 TCP 协议,这四个点都是一致的。
有了 TCP 以后会发生什么? 咱们有了 TCP 以后,咱们基于 TCP 来开发咱们的应用,咱们的应用须要作什么事情? 咱们的应用须要关心 TCP 层下链路层的实现吗?不须要。同理,咱们基于 HTTP 开发应用时,应用须要关心 TCP 层吗?

clipboard.png

为何咱们开发微服务应用的时候就要这么关心服务的通信层?咱们把服务通信层全部的事情学一遍,作一遍,咱们作这么可能是为何?

clipboard.png

这种状况下,天然产生了另一个想法:既然咱们能够把网络访问的技术栈向下移为 TCP,咱们是能够也有相似的,把微服务的技术栈向下移?
最理想的状态,就是咱们在网络协议层中,增长一个微服务层来完成这个事情。可是由于标准问题,因此如今没有实现,暂时这个东西应该不太现实,固然也许将来可能出现微服务的网络层。
以前有一些先驱者,尝试过使用代理的方案,常见的 nginx,haproxy,apache 等代理。这些代码和微服务关系不大,可是提供了一个思路:在服务器端和客户端之间插入了一个东西完成功能,避免二者直接通信。固然代理的功能很是简陋,开发者一看,想法不错,可是功能不够,怎么办?

clipboard.png

这种状况下,第一代的 Sidecar 出现了,Sidecar 扮演的角色和代理很像,可是功能就齐全不少,基本上原来微服务框架在客户端实现的功能都会对应实现。
第一代的 sidecar 主要是列出来的这几家公司,其中最有名气的仍是 netflix。
在这个地方咱们额外提一下,注意第四个,前面三个功能都是国外的公司,可是其实 sidecar 这个东西并非只有国外的人在玩,国内也有厂商和公司在作相似的事情。好比惟品会,我当年在惟品会基础架构部工做的时候,在 2015 年上半年,咱们的 OSP 服务化框架作了一个重大架构调整,加入了一个名为 local proxy 的 Sidecar。注意这个时间是 2015 上半年,和国外差很少。相信国内确定还有相似的产品存在,只是不为外界所知。

clipboard.png

这个时期的 Sidecar 是有局限性的,都是 为特定的基础设施而设计,一般是和当时开发 Sidecar 的公司本身的基础设施和框架直接绑定的,在原有体系上搭出来的。这里面会有不少限制,一个最大的麻烦是没法通用:没办法拆出来给别人用。好比 Airbnb 的必定要用到 zookeeper,netflix 的必定要用 eureka,惟品会的 local proxy 是绑死在 osp 框架和其余基础设施上的。
之因此出现这些绑定,主要缘由仍是和这些 sidecar 出现的动机有关。好比 netflix 是为了让非 JVM 语言应用接入到 Netflix OSS 中,soundcloud 是为了让遗留的 Ruby 应用可使用到 JVM 的基础设置。而当年咱们惟品会的 OSP 框架,local proxy 是为了解决非 Java 语言接入,还有前面提到的业务部门不肯意升级的问题。这些问题都比较使人头疼的,可是又不得不解决,由于逼的憋出来 sidecar 这个一个解决方式。
由于有这样的特殊的背景和需求,因此致使第一代的 Sidecar 没法通用,由于它原本就是作在原有体系之上的。虽然不能单独拿出来,可是在原有体系里面仍是能够很好工做的,所以也没有动力作剥离。致使虽然以前有不少公司有 Sidecar 这个东西,可是其实一直没怎么流传出来,由于即便出来之后别人也用不上。
这里提一个事情,在 2015 年年中的时候,咱们当时曾经有一个想法,将 Local proxy 从 OSP 剥离,改造为通用的 Sidecar。计划支持 HTTH1.1,操做 http header 就能够,body 对咱们是能够视为透明的,这样就容易实现通用了。惋惜由于优先级等缘由未能实现,主要是有大量的其余工做好比各类业务改造,这个事情必要性不够。
全部比较遗憾,当时咱们有这个想法没作实现,这是在 2015 年,时间点很是早的了。若是当时有实现,极可能咱们就本身折腾出业界第一个 service mesh 出来了。如今想一想挺遗憾的。

clipboard.png

可是,不仅有咱们会有这想法。还有有一些人想法和咱们差很少,可是比较幸运的是,他们有机会把东西作出来了。这就是第一代的 Service Mesh,通用性的 sidecar。
通用型的 Service Mesh 的出现,左边第一个 Linkerd 是业界第一个 Service Mesh,也就是它创造了 Service Mesh 这个词。时间点:2016 年 1 月 15 号,0.0.7 发布,这是 github 上看到的最先的一个版本,其实这个版本离咱们当时的有想法的时间点很是近。而后是 1.0 版本,2017 年 4 月份发布,离如今六个月。因此说,Service Mesh 是一个很是新的名词,你们没听过很是正常。
接下来是 Envoy,2016 年发布的 1.0 版本。
这里面要特别强调,Linkerd 和 Envoy 都加入了 CNCF,Linkerd 在今年 1 月份,而 Envoy 进入的时间是 9 月份,离如今也才 1 个月。在座的各位应该都明白 CNCF 在 Cloud Native 领域是什么江湖地位吧?能够说 CNCF 在 Cloud Native 的地位,就跟二战后联合国在国际秩序中的地位同样。
以后出现了第三个 Service Mesh,nginmesh,来自于你们熟悉的 nginx,2017 年 9 月发布了第一个版本。由于实在太新,还在刚起步,没什么能够特别介绍的。

clipboard.png

咱们来看一下 Service Mesh 和 Sidecar 的差别,前面两点是已经提到了:

  1. 首先 Service Mesh 再也不视为单独的组件,而是强调链接造成的网络
  2. 第二 Service Mesh 是一个通用组件

而后要强调的是第三点,Sidecar 是可选的,允许直连。一般在开发框架中,原生语言的客户端喜欢选择直连,其余语言选择走 sidecar。好比 java 写的框架,java 客户端直连,php 客户端走 sidecar。可是也能够都选择走 sidecar,好比惟品会的 OSP 就是全部语言都走 local proxy。在 sidecar 中也是可选的。可是,Service Mesh 会要求彻底掌控全部流量,也就是全部的请求都必须经过 service mesh。

clipboard.png

接下来给你们介绍 Istio,这个东西我给它的评价是 王者风范,来自于谷歌、IBM 和 Lyft,是 Service Mesh 的集大成者。
你们看它的图标,就是一个帆船。Istio 是希腊语,英文语义是 "sail", 翻译过来是起航的意思。你们看这个名字和图标有什么联想?google 在云时代的另一个现象级产品,K8S,kubernete 也一样起源于希腊语,船长,驾驶员或者舵手,图标是一个舵。
istio 名字和图标与 k8s 能够说是一脉相承的。这个东西在 2017 年 5 月份发布了 0.1,就在两周前的 10 月 4 号发布了 0.2。你们都熟悉软件开发,应该明白 0.1/0.2 在软件迭代中是什么阶段。0.1 大概至关于婴儿刚刚出世,0.2 还没断奶。可是,即便在这么早期的版本中,我对他的评价已是集大成者,王者风范,为何?

clipboard.png

为何说 Istio 王者风范?最重要的是他为 Service Mesh 带来了史无前例的控制力。以 Sidecar 方式部署的 Service Mesh 控制了服务间全部的流量,只要可以控制 Service Mesh 就可以控制全部的流量,也就能够控制系统中的全部请求。为此 Istio 带来了一个集中式的控制面板,让你实现控制。
左边是单个视图,在 sidecar 上增长了控制面板来控制 sidecar。这个图还不是特别明显,看右边这个图,当有大量服务时,这个服务面板的感受就更清晰一些。在整个网络里面,全部的流量都在 Service Mesh 的控制当中,全部的 Service Mesh 都在控制面板控制当中。能够经过控制面板控制整个系统,这是 Istio
他的评价

clipboard.png

Istio 由三个公司开发,前两个比较可怕,谷歌和 IBM,并且都是云平台,谷歌的云平台,IBM 的云平台,尤为 GCP 的大名想必你们都知道。所谓出身名门,大概指的就是这个样子吧?
Istio 的实力很是强,我这里给了不少的赞誉:设计理念很是新颖前卫,有创意,有魄力,有追求,有格局。Istio 的团队实力也很是惊人,你们有空能够去看看 istio 的委员会名单感觉一下。Istio 也是 google 的新的重量级的产品,颇有可能成为下一个现象级的产品。Google 如今的现象级产品是什么?K8s。而 Istio 颇有可能成为下一个 K8S 级别的产品。
说到应时而生,什么是势?咱们今天所在的是什么时代?是互联网技术大规模普及的时代,是微服务容器如日中天的时代,是 Cloud Native 大势已成的时代。也是传统企业进行互联网转型的时代,今天的企业用户都想转型,这个大势很是明显,你们都在转或者准备转,可是先天不足。什么叫先天不足?没基因,没能力,没经验,没人才,并且面临咱们前面说的全部的痛点。全部说 Istio 如今出现,时机很是合适。别忘了 istio 身后还有 CNCF 的背景,已经即将一统江湖的 k8s。
istio 在发布以后,社区响应积极,所谓应者云集。其中做为市面上仅有的几个 Service Mesh 之一的 Envoy,甘心为 istio 作底层,而另外两个实现 Linkerd/nginmesh 也直接放弃和 istio 的对抗,选择合做,积极和 istio 作集成。社区中的一众大佬,如这里列出来的,都在第一时间响应,要和 istio 作集成或者基于 istio 作本身的产品。为何说是第一时间?istio 出 0.1 版本,他们就直接代表态度开始站队了。

clipboard.png

Istio
clipboard.png
面的数据面板,是给传统 service mesh 的,目前是 Envoy,可是咱们前面也提到 linkerd 和 nginmesh 都在和 istio 作集成,指的就是替代 Envoy 作数据面板。
另一大块就是上面的控制面板,这是 istio 真正带来的内容。主要分红三大块,图中我列出了他们各自的职责和能够实现的功能。
由于时间有限,不在今天具体展开。

clipboard.png

相关文章
相关标签/搜索