文章目录
Service Mesh 服务网格 ,于2016年9月29日由开发Linkerd的Buoyant公司首次提出,随着2017年Linkerd加入CNCF(云原生计算基金会),Service Mesh开始大规模出现在各个技术论坛。
它被称为下一代微服务技术的代名词,大有一统微服务时代的趋势。
那什么是 Service Mesh?答:Service Mesh 是微服务时代的 TCP/IP协议。
在说Service Mesh之前,就不得不提微服务。根据维基百科的定义:
微服务 (Microservices) 是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块 (Small Building Blocks) 为基础,利用模块化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关 (Language-Independent/Language agnostic) 的 API 集相互通信。
目前和微服务相关的框架和平台更是不胜枚举:Spring Cloud, Service Fabric,Linkerd,Envoy,Istio …
这些项目与Sevice Mesh有什么样的关联?哪些属于Service Mesh的范畴?
我们先来了解下微服务和Service Mesh技术的历史发展脉络。
微服务和Service Mesh技术的发展历程
微服务和Service Mesh的发展历程,也是计算机间进行通信的发展历程。
设想
自从第一次考虑让两台或两台以上的计算机相互通信以来,开发人员想象中,不同服务间通信的方式,抽象表示如下:
一个服务与另一个服务进行对话,以实现最终用户的某些目标。这显然是一个过于简单化的观点,忽略了很多细节。
时代1:原始通信时代
然而现实远比想象的复杂,在实际情况中,通信需要底层能够传输字节码和电子信号的物理层来完成,在TCP/IP协议出现之前,服务需要自己处理网络通信所面临的丢包、乱序、重试、编解码等一系列流控问题,因此服务实现中,除了业务逻辑外,还夹杂着对网络传输问题的处理逻辑。抽象表示如下:
这对开发者而言,意味着的是繁重的工作量,同时也存在着重复造轮子的情况。并且也要保证两台计算机采用的是相同的编码解码规范。
时代2:TCP时代
为了避免每个服务都需要自己实现一套相似的网络传输处理逻辑,TCP/IP协议(发明者:罗伯特·艾略特·卡恩)出现了,它解决了网络传输中通用的流量控制问题,将技术栈下移,从服务的实现中抽离出来,成为操作系统网络层的一部分。这样计算机间的通信就变成这个样子:
时代3:第一代微服务(过渡)
在TCP/IP协议出现之后,机器之间的网络通信不再是一个难题,同时随着时代和技术的发展,人们对计算机可以实现的功能也有了更高的要求,这样的需求也进一步推动了软件行业的发展,软件架构也经历了单体架构到微服务架构的转变,以GFS(分布式文件系统)/BigTable(分布式数据存储系统)/MapReduce(并行计算)为代表的分布式系统得以蓬勃发展。这时,分布式系统特有的通信语义又出现了,如:服务注册与发现、负载均衡、熔断降级、限流、认证和授权、服务配置、trace和监控等等,于是这时期的系统服务根据业务需求来实现这些通信语义(功能)。
时代4:第二代微服务
历史总是惊人的相似。
为了避免每个服务都需要自己实现一套分布式系统通信的语义功能,随着技术的发展,一些面向微服务架构的开发框架出现了,如Spring Cloud、Twitter的Finagle、Facebook的Proxygen等等,这些框架实现了分布式系统通信需要的各种通用语义功能:如负载均衡和服务发现等,因此一定程度上屏蔽了这些通信细节,使得开发人员使用较少的框架代码就能开发出健壮的分布式系统。
目前,这种架构体系依然占据大多数。
时代5:Service Mesh探索
第二代微服务模式看似完美,但开发人员很快又发现,它也存在一些问题:
- 一、虽然框架本身屏蔽了分布式系统通信的一些通用功能实现细节,但开发者却要花更多精力去掌握和管理复杂的框架本身,在实际应用中,去追踪和解决框架出现的问题也绝非易事;
- 二、开发框架通常只支持一种或几种特定的语言,回过头来看文章最开始对微服务的定义,一个重要的特性就是语言无关,但那些没有框架支持的语言编写的服务,很难融入面向微服务的架构体系,想因地制宜的用多种语言实现架构体系中的不同模块也很难做到;
- 三、框架以lib库的形式和服务联编,复杂项目依赖时的库版本兼容问题非常棘手,同时,框架库的升级也无法对服务透明,服务会因为和业务无关的lib库升级而被迫升级;
那怎么解决这些问题呢?参考TCP/IP协议的产生,将大规模分布式服务所需的功能提取到底层平台中是非常可取的。
还有在微服务中,从事服务工作的工程师可以专注于他们的业务逻辑,避免在编写自己的服务基础设施代码或管理整个团队的库和框架时浪费时间。就像:人们在使用HTTP等更高级别的协议编写非常复杂的应用程序和服务时,不会去考虑TCP/IP协议如何控制网络上的数据包。这种情况正是我们微服务所需要的,将这个想法抽象下,我们最终可能会得到以下内容:
不幸的是,在操作系统中添加此层是不可行的。但是前辈们发现了另外一个解决方案是:将其作为一组代理来实现。具体想法是,服务不会直接连接到其下游依赖项,而是通过一个与其对应的代理管理所有流量。Sidecar(边车)模式应运而生,sidecar是一个辅助进程,它将运行您的应用程序并为其提供额外的功能,这一点和AOP(面向切面编程)很是相似。它将分布式服务的通信抽象为单独一层,在这一层中实现负载均衡、服务注册与发现、认证授权、监控追踪、流量控制等分布式系统所需要的功能,作为一个和服务对等的代理服务,和服务部署在一起,接管服务的流量,通过代理之间的通信间接完成服务之间的通信请求。
在Sidecar(边车)模式刚诞生时,2013年,Airbnb写了一篇关于Synapse和Neve的文章,这是他们使用边车模式实现的一个开源项目。一年后,Netflix(网飞)推出了Prana,这是也是一个使用边车模式的项目,致力于让非JVM应用程序从其NetflixOSS生态系统中受益。虽然有了几种开源的边车代理实现,但它们往往是为与特定的基础设施组件一起工作而设计的。例如,当涉及到服务发现时,Airbnb的Synapse&Nerve假设服务在Zookeeper中注册,而对于Prana,应该使用Netflix自己的Eureka服务注册。
虽然此时还存在着一些瑕疵,但已经具备了Service Mesh的雏形,如果我们从一个全局视角来看,就会得到如下部署图:
我们暂时省略服务,只看Service Mesh的单机组件组成的网络。它看起来确实就像是一个由若干服务代理所组成的错综复杂的网格。这也就是服务网格了。
时代6:Service Mesh
在探索者的努力下,Service Mesh得到进一步的完善,它足够灵活,可以适应不同的基础设施组件。之前Service Mesh由一系列独立运行的单机代理服务构成,为了提供统一的上层运维入口,演化出了集中式的控制面板,所有的单机代理组件通过和控制面板交互进行网络拓扑策略的更新和单机数据的汇报。这就是以 Istio 为代表的第二代Service Mesh。
只看单机代理组件(数据面板)和控制面板的Service Mesh全局部署视图如下。从视图中可以看出,实际的服务流量仍然直接从一个代理流到另一个代理,但控制面板知道每个代理实例的操作,这样就能够实现访问控制和度量收集等功能。
小结
现在,我们来看下Buoyant的CEO William Morgan,也就是Service Mesh这个词的发明人,对Service Mesh的定义:
服务网格是一个基础设施层,用于处理服务间通信。云原生应用有着复杂的服务拓扑,服务网格保证请求在这些拓扑中可靠地穿梭。在实际应用当中,服务网格通常是由一系列轻量级的网络代理 组成的,它们与应用程序部署在一起,但对应用程序透明。
Service Mesh的目标是要将微服务治理体系下沉为与业务无关的基础设施。实际上Service Mesh微服务治理技术的诞生也不是凭空产生的,而是在以Kubernetes为代表的容器编排技术逐步成为软件运行主流基础环境的背景下,以及以Spring Cloud框架为代表的传统微服务技术体系弊端逐步显现的情况下技术自然迭代发展的结果。
所以Service Mesh和云原生的强联系的。
在Service Mesh中,当我们将一个服务部署在Kubernetes之后,安装在Kubernetes中的Service Mesh组件(例如Istio)就会自动在该微服务的同一个Pod之中启动一个与之对应的代理进程(例如istio-proxy),这个保姆式的代理进程会代替微服务本身去实现原先在Spring Cloud体系中需要微服务自身完成的服务注册、负载均衡、熔断限流、监控日志等微服务治理功能。并且,这些代理进程并不是孤军奋战,而是会通过XDS协议(Service Mesh中数据面与控制面通信的通用协议)与Service Mesh控制组件保持连接。
也正是因为将这些微服务治理功能放在代理进程中实现,所以才能做到与编程语言无关。
总结一下,Service Mesh具有如下优点:
- 屏蔽了分布式系统通信的复杂性(负载均衡、服务发现、认证授权、监控追踪、流量控制等等),让服务只用关注业务逻辑;
- 真正的语言无关,服务可以用任何语言编写,只需和Service Mesh通信即可;
- 对应用透明,Service Mesh组件可以单独升级;
当然,Service Mesh目前也面临一些挑战:
- Service Mesh组件以代理模式计算并转发请求,一定程度上会降低通信系统性能,并增加系统资源开销;
- Service Mesh组件接管了网络流量,因此服务的整体稳定性依赖于Service Mesh,同时额外引入的大量Service Mesh服务实例的运维和管理也是一个挑战;
实际上,如果在一个小公司,Service Mesh的优势体现的并不是十分明显。因为这些公司很少会考虑采用多语言,因为多一种语言就意味着要分散额外的精力进行维护,所以到目前为止,大多数公司在后端只使用一两种语言。另外,微服务框架相对来说比较稳定,就如同Spring Framework一样,不会轻易进行不兼容的升级,只要保持好节奏,问题不会太多。
此外,Service Mesh降低开发人员的门槛也并没有那么明显,因为完全不考虑是不可能的,Service Mesh在没有理解业务的情况下,是不能私自做决定的。例如A服务调用B服务的超时时间,设置多少合理呢?还是需要开发人员根据业务进行配置的。
还有,Service Mesh对业务开发人员友好,但是基础设施层的研发会更复杂,需要依赖更多的服务、组件,将带来较大的架构、运维复杂度。对于很多公司来说,门槛稍高,且需要投入成本。
因此,对于绝大多数公司来说,Service Mesh并不具备压倒性的优势,在没有成熟起来以前,大多都是观望状态。目前也只是一些头部公司在使用,现在比较知名的项目有:
产品 | 数据面 | 控制面 |
---|---|---|
Istio(Lyft、IBM与google联合开发) | Envoy(C++) | pilot(Golang),与k8s强耦合 |
TSF(腾讯) | Envoy(C++) | pilot(Golang),基于pilot二次开发,解耦了k8s |
ByteMesh(字节) | Envoy(C++) | 自研 |
OctoMesh(美团) | Envoy(C++) | 自研 |
SofaMesh(蚂蚁金服) | mosn(Golang) | pilot(Golang),开源可对接istio |
cesMesh(华为) | 自研(Golang) | 自研(Golang) |
参考资料: