五分钟了解 Service Mesh
1 背景
1.1 多语言
微服务理念是提倡不同业务使用最适合它的语言开发,现实情况也确实如此,尤其是AI的兴起,一般大型互联网公司存在 C/C++、Java、Golang、PHP、Python、NodeJs 等语言的项目,这就意味着每种语言都需要实现了相同功能服务框架。然而,服务框架的 SDK 通常实现都比较重,需要实现服务注册与发现、服务路由、负载均衡、服务鉴权、服务降级、服务限流、网络传输等功能,所以这块的成本不言而喻。
1.2 产品交付
在伴随着服务组件的功能升级,bug 修复过程中,业务系统需要升级依赖的服务组件包,升级中还可能存在各种版本冲突,而且灰度验证过程也可能存在 bug,业务升级版本痛苦不堪,往往一个组件包想要全覆盖升级,需要耗费相当长的时间,交付效率极其低下。随着业务的不断发展,业务的规模和我们交付的效率已经成为主要的矛盾,所以组件团队期望以更高的效率去研发基础设施,而不希望基础设施的迭代受制于这个组件的使用规模。
1.3 云原生
在云原生架构里,单个应用程序可能由数百个服务组成; 每个服务可能有数千个实例; 而且这些实例中的每一个都可能处于不断变化的状态,因为它们是动态调度一个像 Kubernetes 一样的编排器。服务间通信不仅异常复杂,而且也是运行时行为的基础。管理好服务间通信对于保证端到端的性能和可靠性来说是非常重要的。因此,管理好服务间通信对于保证端到端的性能和可靠性来说是非常重要的。
基于以上背景,Service Mesh 产生了。
2 是什么
在上述背景下业界也做了一些探索,比如唯品会在服务调用方增加了 Proxy 层,将服务组件公共的逻辑功能放在 Proxy 中实现,剩下与业务交互的 API 功能放在 Client 中实现,这样来降低多语言的成本。另外,新浪微博也使用 Proxy 方案提供小众语言的服务注册和调用的支持。其实这种 Proxy 结构类似现在的 Service Mesh,只是当时还没有 Service Mesh 这个名词。
在 2016 年 Buoyant 的 CEO William 提出了 Service Mesh 的概念。Service Mesh 是一种基础设施层,主要处理服务间的通信,在复杂的云原生服务拓扑中,负责请求的可靠传递。一般实现为网络代理,通常与业务服务部署在一起,业务服务不感知。
3 能做什么
3.1 服务发现
以微服务模式运行的应用变更非常频繁,应用实例的频繁增加减少带来的问题是如何精确地发现新增实例以及避免将请求发送给已不存在的实例变得更加复杂。Service Mesh 可以提供简单、统一、平台无关的多种服务发现机制,如基于 DNS,K/V 键值对存储的服务发现机制。
3.2 动态路由
随着服务提供商以提供高稳定性、高可用性以及高 SLA 服务为主要目标,为了实现所述目标,出现各种应用部署策略尽可能从技术手段达到无服务中断部署,以此避免变更导致服务的中断和稳定性降低,例如:Blue/Green 部署、Canary 部署,但是实现这些高级部署策略通常非常困难。如果可以轻松的将应用流量从一个版本切到另外一个版本,更或者从一个数据中心到另外一个数据中心进行动态切换,甚至可以通过一个中心控制层控制多少比例的流量被切换。那么 Service Mesh 提供的动态路由机制和特定的部署策略如 Blue/Green 部署结合起来,实现上述目标更加容易。
3.3 负载均衡
运行环境中微服务实例通常处于动态变化状态,而且经常可能出现个别实例不能正常提供服务、处理能力减弱、卡顿等现象。但由于所有请求对 Service Mesh 来说是可见的,因此可以通过提供高级负载均衡算法来实现更加智能、高效的流量分发,降低延时,提高可靠性。
3.4 请求熔断
动态的环境中服务实例中断或者不健康导致服务中断可能会经常发生,这就要求应用或者其他工具具有快速监测并从负载均衡池中移除不提供服务实例的能力,这种能力也称熔断,以此使得应用无需消耗更多不必要的资源不断地尝试,而是快速失败或者降级,甚至这样可避免一些潜在的关联性错误。而 Service Mesh 可以很容易实现基于请求和连接级别的熔断机制。
3.5 安全通讯
无论何时,安全在整个公司、业务系统中都有着举足轻重的位置,也是非常难以实现和控制的部分。而微服务环境中,不同的服务实例间通讯变得更加复杂,那么如何保证这些通讯是在安全、授权情况下进行非常重要。通过将安全机制如 TLS 加解密和授权实现在 Service Mesh 上,不仅可以避免在不同应用的重复实现,而且很容易在整个基础设施层更新安全机制,甚至无需对应用做任何操作。
3.6 多语言支持
由于 Service Mesh 作为独立运行的透明代理,很容易支持多语言。
3.7 多协议支持
同多语言支持一样,实现多协议支持也非常容易。
3.8 Metric和链路追踪
Service Mesh 对整个基础设施层的可见性使得它不仅可以暴露单个服务的运行数据,而且可以暴露整个集群的运行数据。
3.9 重试
Service Mesh 的重试功能避免将其嵌入到业务代码,同时最后期限使得应用允许一个请求的最长生命周期,而不是无休止的重试。
4 如何实现
Service Mesh 最终实现是使用 Sidecar 边车部署方式,将服务发现,服务路由,负载均衡等功能实现在 Sidecar 内,Sidecar 作为一个单独的进程与业务服务部署在同一个机器上。 Sidecar 内部的具体实现称为数据平面,而作为 Sidecar 的控制逻辑,称之为控制平面。
如上图中,应用作为服务的发起方,只需要用最简单的方式将请求发送给本地的服务网格代理,然后网格代理 Sidecar 会进行后续的操作,如服务发现,负载均衡等,最后将请求转发给目标服务。当有大量服务相互调用时,它们之间的服务调用关系就会形成一种类似网格的形式。
Service Mesh 给基础组件带来了新的方向,可以通过 Service Mesh 的 Sidecar,将基础组件的功能下层到 Sidecar 内,对业务透明,方便升级维护,并且解决多语言的问题。
5 优势
5.1 多语言
由于 Service Mesh 共享了大部分的组件功能,所以在多语言实现上,更加简单,各自的语言只需实现一些简单的逻辑,就能提供的服务组件所有功能,从而大大降低多语言服务组件的实现成本。
5.2 产品交付
组件的大部分功能移至 Service Mesh 中,与业务逻辑隔离,可单独进行升级,运维,对业务透明,提升了组件的交付能力。超越 Spring Cloud 和 Dubbo 等传统开发框架之处在于不仅仅带来了远超这些框架所能提供的功能,更重要的是不需要应用程序为此做大量的改动, 开发人员也不必为上面的功能实现进行大量的知识储备,降低学习服务组件的使用成本。
5.3 云原生
在复杂的云原生架构中,Service Mesh 能更好的管理服务间通信对于保证端到端的性能和可靠性来说是非常重要的。
6 问题
6.1 性能
Service Mesh 方式的服务调用,相比服务框架的直接调用,增加了与 Service Mesh 中 Sidecar 的交互,必然会牺牲部分性能,但由于是本地网络通信,不经过网络层传输,其性能损耗应该在可控范围内。
6.2 可用性
Service Mesh 方式是通过单独的本地进程来提供为应用程序提供服务,也就在整个服务调用链上增加了故障点,势必会导致可用性下降,这就对 Service Mesh 的整体设计提出了更高的要求,来保证服务的可用性。
7 展望
有文章提到 Service Mesh 将是下一代服务架构,我们也期待 Service Mesh 更好的发展,给业务提升更多的便利,降低开发成本,提供更好的技术服务。
喜欢本文的同学,可以关注涤生的博客