Service Mesh

Service Mesh

简介

Service Mesh是用于处理服务到服务通信的专用基础架构层。
实际上,Service Mesh通常作为一组轻量级网络代理实现,这些代理与应用程序代码部署在一起,应用程序无感知。

随着 Cloud Native 的崛起,Service Mesh 逐步发展为一个独立的基础设施层。
在Cloud Native 架构下,单个应用程序可能由数百个服务组成;每个服务可能有数千个实例;
并且这些实例中的每一个实例都可能处于不断变化的状态,因为它们是由诸如Kubernetes之类的资源调度系统动态调度的。
这个世界中的服务通信不仅非常复杂,而且是运行时行为的普遍和基本部分,管理它对于确保端到端的性能和可靠性至关重要。

简单来说,Service Mesh 帮助应用程序在海量服务、复杂的架构和网络中建立稳定的通信机制,
业务所有的流量都转发到 Service Mesh 的代理服务中,
不仅如此,Service Mesh还承担了微服务框架所有的功能,包括服务注册发现、负载均衡、熔断限流、认证鉴权、缓存加速等。
不同的是,Service Mesh强调的是通过独立的进程代理的方式,除此之外,还承担了上报日志、监控的责任。

Service Mesh被翻译为“服务网格”,或者“服务啮合”, 也被很多人将称为下一代微服务,或直接称之为微服务2.0。
微服务的概念在2014年3月由Martin Fowler首次提出,Service Mesh的概念则是在2016年左右提出。
微服务1.0时代的主要问题主要包括如下三方面:

技术门槛高:
开发团队在实施微服务的过程中,除了基础的服务发现、配置中心和鉴权管理之外,团队在服务治理层面面临了诸多的挑战,包括负载均衡、熔断降级、灰度发布、故障切换、分布式跟踪等,这对开发团队提出了非常高的技术要求。

多语言支持不足:
对于互联网公司,尤其是快速发展的互联网创业公司,多语言的技术栈、跨语言的服务调用也是常态,但目前开源社区上并没有一套统一的、跨语言的微服务技术栈,而跨语言调用恰恰是微服务概念诞生之初的要实现的一个重要特性之一。

代码侵入性强:
Spring Cloud、Dubbo等主流的微服务框架都对业务代码有一定的侵入性,技术升级替换成本高,导致开发团队配合意愿低,微服务落地困难。

Sidecar是Service Mesh中的重要组成部分,Sidecar的精髓在于实现了数据面(业务逻辑)和控制面的解耦。
在Service Mesh架构中,给每一个微服务实例部署一个Sidecar Proxy。该Sidecar Proxy负责接管对应服务的入流量和出流量,并将微服务架构中的服务订阅、服务发现、熔断、限流、降级、分布式跟踪等功能从服务中抽离到该Proxy中。
Sidecar以一个独立的进程启动,可以每台宿主机共用同一个Sidecar进程,也可以每个应用独占一个Sidecar进程。
所有的服务治理功能,都由Sidecar接管,应用的对外访问仅需要访问Sidecar即可。
当该Sidecar在微服务中大量部署时,这些Sidecar节点自然就形成了一个服务网格。

Service Mesh至今也经历了第二代的发展。

第一代Service Mesh的代表为Linkerd和Envoy,这两个开源实现都是以Sidecar为核心,绝大部分关注点都是如何做好Proxy,并完成一些通用控制面的功能。
Envoy底层基于C++,性能上优于使用Scala的Linkrd。同时,Envoy社区成熟度较高,商用稳定版本面世时间也较长。
但是当在容器中大量部署Sidecar以后,如何管理和控制这些Sidecar本身就是一个不小的挑战。

第二代Service Mesh主要改进集中在更加强大的控制面功能(与之对应的Sidecar Proxy被称之为数据面),典型代表有Istio和Conduit。
Istio是Google、IBM和Lyft合作的开源项目,是目前最主流的Service Mesh方案,也是事实上的第二代Service Mesh标准。在Istio中,直接把Envoy作为Sidecar。除了Sidecar,Istio中的控制面组件都是使用Go语言编写。

对于大规模部署微服务,内部服务异构程度高的场景,使用Service Mesh方案是一个不错的选择。
Service Mesh实现了业务逻辑和控制的解耦,但是也带来了额外的开销,由于网络中多了一跳,增加了性能的损耗和访问的延迟。
同时,由于每个服务都需要部署Sidecar, 这也会使本来就具有一定复杂度的分布式系统变得更加复杂。
尤其是在实施初期,对Service Mesh的管理和运维会是一个棘手的问题。
因此,当选择使用Service Mesh架构的时候,需要对具体的Service Mesh实现方案(例如:Istio)做好充分的技术准备和经验积累工作,方能确保方案的顺利实施。

为什么需要Service Mesh

Service Mesh的出现是由微服务架构推动的,随着一个应用被拆分成几百个甚至几万个应用,服务治理面临巨大的挑战。
微服务框架基于客户端负载均衡直连的方式,此方案的优势是性能高、应用性好。
如果使用Java语言,可以直接引入JAR包,通过简单的配置,就可以实现微服务之间的通信。

归根结底,在微服务架构中,要解决的问题是,让开发人员感觉不到微服务之间的通信。
当服务数量越来越多,升级微服务框架变得越来越复杂的时候,不可能要求微服务框架一直不变,而且是没有bug的。
在技术更新速度如此之快的年代,就更不可能了。
因此,微服务框架的部分功能开始逐步向服务端移动,希望客户端可以尽量"薄”,但是客户端不可能无限制的“薄”,剩余部分仍然比较“厚”。

因为使用客户端更像一种交付的模式,不容易变更,控制力较差,
而Service Mesh则从业务进程集成客户端的方式演进为独立进程的方式,
也就是说将原本的客户端变成了一个独立进程。对这个独立进程升级、运维要比绑在一起强得多。

微服务架构更强调去中心化、独立自治、跨语言,但是通常微服务框架限制了这一点,不可能为每种语言都实现一个框架,要么都用一种语言,要么实现多种语言的框架。
而Service Mesh 通过独立进程的方式进行了隔离,可以低成本实现跨语言。

随着Docker及Kubernetes的崛起,微服务的部署模式开始发生转变,越来越趋向于轻量级,越来越强调隔离自治。
每个服务独立占用一个容器,将服务、依赖包、操作系统、监控运维所需的代理打包成一个镜像。
这种模式促成了Service Mesh的发展,让ServiceMesh 实现起来更容易。否则开发人员需要额外维护 Service Mesh 进程,就非常麻烦了。

实际上,如果在一个小公司, Service Mesh的优势并不是十分明显。
例如小公司很少会考虑采用多语言,因为多一种语言就意味着要花费额外的精力进行维护,所以到目前为止,大多数公司在后端只使用一两种语言。
另外,微服务框架相对来说比较稳定,就如同Spring Framework一样,不会轻易进行不兼容的升级,只要保持好节奏,问题不会太多。

初见


posted @ 2017-04-27 22:58  Anliven  阅读(511)  评论(0编辑  收藏  举报