Service Mesh 入门之Service Mesh简介

从这篇文章开始,我将分多篇文章来讨论最近今年比较热门的Service Mesh相关技术,Service Mesh在国内被翻译为「服务网格」或「网格计算」。

按内容由浅入深大体分为三个部分,分别是入门、进阶和实战。

在此过程中,也会穿插介绍这方面的一些知名开源解决方案。

言归正传,在这第一篇中,我们首先来了解下Service Mesh相关的基础概念,它出现的背景,它能够解决的问题以及目前业界已有那些Service Mesh产品。

微服务架构面临的主要挑战及Service Mesh出现的背景

近年来,大大小小的公司都有过微服务实践,最主要原因我认为有两方面:云计算技术的快速发展和其能够解决单体架构面临的一些问题。

关于微服务架构能够解决单体架构的哪些问题,请自行查阅,此文不再赘述。

对微服务的定义,从不同角度也有不同的定义方法,但用一句话来说的话,就是将单体架构的各类功能,按照业务功能或者其他纬度进行系统拆分,拆分后的各个系统之间通过接口的方式进行调用。

于是,微服务架构中各系统之间运转良好的强依赖,就是网络。

关于分布式系统高可用的著名的八大谬误,都是关于网络的:


网络是可靠的网络零延迟网络带宽是无限的网络是安全的网络拓扑一成不变只有一个系统管理员传输代价为零网络是同质

微服务虽然解决了单体架构的一些问题,如编程语言只能限定为一种、部署困难、测试难度大等。但正如《人月神话》开篇所说:没有银弹。微服务架构也并不是万能的,引入微服务体系后,又会带来新的问题。

其中最大的挑战便是如何以标准化的方式管理微服务以及如何保证复杂网络环境中微服务间的可靠通信(针对上述八个谬误的解决方案),确保整个系统的最大可用性,提供尽可能高的SLA(Service-Level Agreement,服务等级协议)。

 

清楚地认识这八大谬误对构建分布式系统非常重要,但是,诸多原因使得构建一个高可用、弹性的分布式系统仍然非常困难,比如:网络不可靠、不可避免的系统依赖组件失败、用户行为的不可预知等。

 

当然,这并不意味着构建高可用、弹性的分布式系统是不可能的。

 

事实上,业界多年的技术积累及经验总结,已经提出很多有助于提高系统可用性和弹性的通用型技术指南,那就是模式(比如程序设计模式、企业软件设计模式,架构同样也有模式可以遵循)。

 

可以说,模式在软件工程中无处不在。以下是一些在构建分布式软件或者普通软件时的常用模式。

超时(Timeout):超时使得如果访问下游服务缓慢或失败时,上游服务应快速失败而不是无限或者长时间等待,以此避免级联故障,隔离故障范围。

❑ 重试(Retry):重试有效地解决访问服务时发生的间隙性故障,有助于减少服务恢复时间。

❑ 熔断(Circuit Breaker):熔断机制避免将请求继续发送给已经失败或者不健康的下游服务处理,而是等待它们恢复,避免级联故障。

❑ 健壮性测试(Resiliency Testing):健壮性测试通过人为的方式向系统注入各种可能的故障,模拟网络故障、延迟、依赖组件故障等,以此提前获得一些未知错误并制定相应的处理方案。

❑ 限速节流(Rate-limiting and Throttling):限速节流限定服务在固定的时间内只处理一定数量的请求,确保系统有足够的能力优雅地处理其他请求,可避免峰值流量导致系统崩溃,与第三方系统集成时可以提供安全保障。

除此以外,还有许多技术可帮助实现分布式系统的高可用性,例如:

❑ 动态服务发现

❑ 负载均衡

❑ 运行时动态路由

❑ 安全通信

❑ 运行时指标及分布式追踪(关于APM,后面再写专题)

正如前文所述,微服务对网络通讯是强依赖。事实上,甚至可以简单地将微服务分为两个部分:业务逻辑和网络功能。

在很多客观情况下,开发人员针对网络功能的精力投入并不会比对业务逻辑对投入少。如果所有的微服务系统团队都需要这样来一遍,从整个微服务系统群的视觉来看,就是可耻的资源浪费。

Service Mesh正是基于这样的背景下,于2016年出现了。它的主要职责,是将与各系统业务逻辑无关的网络功能抽取出来,形成独立的抽象层,在独立层的透明网络代理上实现负载均衡、服务发现、熔断、运行时动态路由等功能,使应用具备处理网络弹性逻辑和提供可靠交互请求的能力。

 

它使得耦合性更低、灵活性更强,跟现有环境的集成时间和人力代价更小,也提供多语言支持、多协议支持,运维和管理成本更低。

 

最主要的是开发人员只需关注业务代码逻辑,而不需要关注业务代码以外的其他功能,换句话说,Service Mesh对开发人员是透明的。

 

什么是Service Mesh?

 

Service Mesh先驱,Buoyant公司的CEOWilliam Morgan,他对Service Mesh的定义如下:

专用基础设施层:独立的运行单元。包括数据平面和控制平面:数据平面负责交付应用请求,控制平面控制服务如何通信。轻量级透明代理:实现形式为轻量级网络代理。处理服务间通信:主要目的是实现复杂网络中服务间通信。可靠地交付服务请求:提供网络弹性机制,确保可靠交付请求。与服务部署一起,但服务感知不到:尽管跟应用部署在一起,但对应用是透明的。

基本架构示意图:

 Service Mesh的功能

❑ 负载均衡:通过提供高级负载均衡算法来实现更加智能、高效的流量分发,降低延时,提高可靠性。

❑ 服务发现:提供简单、统一、平台无关的多种服务发现机制,如基于DNS、K/V键值对存储的服务发现机制,来解决微服务经常升级或伸缩导致服务不可用以及新增服务难以被发现的问题。

❑ 熔断:动态的环境中服务实例中断或者不健康导致服务中断可能会经常发生,这就要求应用或其他工具具有快速监测并从负载均衡池中移除不提供服务实例的能力,这种能力也称熔断,以此使得应用无需消耗更多不必要的资源不断地尝试,而是快速失败或者降级,甚至这样可避免一些潜在的关联性错误。而Service Mesh可以很容易实现基于请求和连接级别的熔断机制。

❑ 动态路由:随着服务提供商以提供高稳定性、高可用性以及高SLA服务为主要目标,为了实现所述目标,出现各种应用部署策略尽可能从技术手段达到无服务中断部署,以此避免变更导致服务的中断和稳定性降低,例如Blue/Green部署和Canary部署,但是实现这些高级部署策略通常非常困难。而如果运维人员可以轻松地将应用流量从staging环境切换到产线环境,一个版本切换到另外一个版本,或者从一个数据中心到另外一个数据中心进行动态切换,甚至可以通过一个中心控制层控制多少比例的流量被切换。那么Service Mesh提供的动态路由机制和特定的部署策略如Blue/Green部署结合起来,实现上述目标将更加容易。

❑ 安全通信:微服务环境中,不同的服务实例间通信变得更加复杂,那么如何保证这些通信是在安全、有授权的情况下进行就非常重要。通过将安全机制如TLS加解密和授权实现在Service Mesh上,不仅可以避免在不同应用上的重复实现,而且很容易在整个基础设施层更新安全机制,甚至无需对应用做任何操作。

❑ 多语言支持:由于Service Mesh作为独立运行的透明代理,很容易支持多语言。

❑ 多协议支持:同多语言支持一样,实现多协议支持也非常容易。

❑ 指标和分布式追踪:Service Mesh对整个基础设施层的可见性使得它不仅可以暴露单个服务的运行指标,而且可以暴露整个集群的运行指标。

❑ 重试和最后期限:Service Mesh的重试功能避免将其嵌入到业务代码,同时最后期限使得应用允许一个请求的最长生命周期,而不是无休止的重试。

概括起来,即Service Mesh使得微服务具有下列性能:

❑ 可见性(visiblity):运行时指标、分布式跟踪。

❑ 可管理性(manageablity):服务发现、负载均衡、运行时动态路由。

 

❑ 健壮性(resilience):超时重试、请求最后期限、熔断机制。

 

❑ 安全性(security):服务间访问控制、TLS加密通信。

 

PS:笔者曾在某公司工作时,关于常规的比如限流、降级、熔断等功能,都是由各个微服务自行负责的。这样的方式会引发诸多问题,如系统实现这些功能的方式不统一,甚至有些实现还存在bug,该熔断的时候没做熔断,导致很多生产事故。Service Mesh正是为了解决这些问题而生。

 

Service Mesh的开源解决方案

 

最后,让我们来看看市面上有哪些优秀的Service Mesh解决方案。

 

这里我先按照出现的时间先后顺序来罗列,在后续的文章中,我将选择其中的一个来做实战练习。

 

1、Linkerd (https://linkerd.io)  :1.x 以Scala语言编写,运行在JVM上,底层基于Twitter的Finagle库,并对其做相应的扩展。2.x以go语言编写,具有快速、轻量级、高性能等特点,每秒以最小的时延及负载处理万级请求,易于水平扩展,经过产线测试及验证,可运行任何平台的产线级Service Mesh工具。

其他特性:

❑ 支持多平台,如Kubernetes、Docker、虚拟机或者物理机。

❑ 无缝集成多种服务发现工具。

❑ 支持多协议,如gRPC、HTTP/2、HTTP/1.x,甚至可通过linkerd-tcp支持TCP协议。

❑ 支持与第三方分布式追踪系统Zipkin集成。

❑ 灵活性、扩展性高,可通过其提供的接口开发自定义插件。

 

PS:由于是Service Mesh的鼻祖,因此采用的公司挺多。

 

2、Envoy(https://www.envoyproxy.io): 以go语言编写,其实现借鉴现有产线级代理及负载均衡器,如Nginx、HAProxy、硬件负载均衡器及云负载均衡器的实践经验,同时基于C++编写及Lyft公司产线实践证明,Envoy性能非常优秀、稳定。Envoy既可用作独立代理层运行,也可作为Service Mesh架构中数据平面层,因此通常Envoy跟服务运行在一起,将应用的网络功能抽象化,Envoy提供通用网络功能,实现平台及语言无关。

 

其他特性:

❑ 大规模负载下,Envoy保证P99延时非常低。

❑ 优先支持HTTP/2和gRPC,同时支持Websocket和TCP代理。

❑ API驱动的配置管理方式,支持动态管理、更新配置以及无连接和请求丢失的热重启功能。

❑ L3/L4层过滤器形成Envoy核心的连接管理功能。

❑ 通过与多种指标收集工具及分布式追踪系统集成,实现运行时指标收集,分布式追踪,提供整个系统及服务的运行时可见性。

❑ 内存资源使用率低,sidecar是Envoy最常用的部署模式。

 

PS:据说腾讯用的是这个工具做服务网格。

 

3、Istio(https://istio.io):使用C++编写的一款开源的为微服务提供服务间连接、管理以及安全保障的平台软件,支持但不限于运行在Kubernetes、Mesos等容器管理工具,底层依赖于Envoy。

 

Istio提供一种简单的方法实现服务间的负载均衡、服务间认证、监控等功能,而且无需应用层代码调整。其控制平面由Mixer、Pilot及Citadel组成,数据平面由Envoy实现,通常情况下,数据平面代理Envoy以sidecar模式部署,使得所有服务间的网络通信均由Envoy实现,而Istio的控制平面则负责服务间流量管理、安全通信策略等功能。由于其底层是Envoy,Envoy支持的各种功能以及Service Mesh要求的功能Istio均支持,除此之外还有以下功能:

 

❑ 完善的流量管理机制,如故障注入。

❑ 增强服务间安全保障,如服务身份认证,密钥管理和基于RBAC的访问控制策略。

❑ 支持多平台部署。

 

4、Conduit( https://conduit.io/ ):Conduit旨在彻底简化用户在Kubernetes使用服务网格的复杂度,提高用户体验,而不是像Linkerd一样针对各种平台进行优化。Conduit的主要目标是轻量级、高性能、安全并且非常容易理解和使用。同Linkerd和Istio, Conduit也包含数据平面和控制平面,其中数据平面由Rust开发,使得Conduit使用极少的内存资源,而控制平面由Go开发。

 

Conduit依然支持ServiceMesh要求的功能,而且还包括以下功能:

❑ 超级轻量级及极快的性能,亚毫秒级P99延迟。

❑ 专注于支持Kubernetes平台,提高运行在Kubernetes平台上服务的可靠性、可见性及安全性。

❑ 支持gRPC、HTTP/2和HTTP/1.x请求及所有TCP流量。

 

以上是按时间先后顺序罗列的四个主要工具,但任何一个新的概念提出后,经历时光流逝,会逐步有一些新的工具出现,也会有一些老的工具被替代后消亡。

 

笔者一般的做法是每过一段时间,便去github.com/google.com等站点去搜索一下,看看是否有新的东西出现。

下面是笔者找到的针对上述四个工具对比的图片,供参考:

 

未经允许不得转载:大自然的搬运工 » Service Mesh 入门之Service Mesh简介

赞 (0)

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址