Service Mesh 是什么?为什么我们需要它?

Service Mesh(服务网格)是一个基础设施层,让服务之间的通信更安全、快速和可靠。如果你在构建云原生应用,那么就需要 Service Mesh。

在过去的一年中,Service Mesh 已经成为云原生技术栈里的一个关键组件。很多拥有高负载流量业务的公司都在他们的生产应用里加入了 Service Mesh,如 PayPal、Lyft、Ticketmaster 和 Credit Karma 等。并且在今年一月份, Linkerd 作为云原生应用程序的开源 Service Mesh,已经成为 CNCF(Cloud Native Computing Foundation)的官方项目。但是 Service Mesh 到底是什么?为什么它突然间变得如此重要?

在这篇文章里,将给出 Service Mesh 的定义,并追溯过去十年间 Service Mesh 在应用架构中的演变过程。解释 Service Mesh 与 API 网关、边缘代理(Edge Proxy)和企业服务总线之间的区别。最后描述 Service Mesh 将如何发展以及我们可以作何期待。

什么是 Service Mesh?

Service Mesh 是用于处理服务间通信的基础设施层。它负责通过构成现代云原生应用程序的复杂拓扑结构来可靠地传递请求。

在实践中,Service Mesh 通常被实现为与应用程序代码一起部署的轻量级网络代理的阵列,而不需要应用程序需要知道。

Service Mesh 作为一个单独的层的概念与云原生应用程序的兴起息息相关。在云原生模型里,单个应用程序可能由数百个服务组成; 每个服务可能有数千个实例; 而且这些实例中的每一个都可能处于不断变化的状态,因为它们是动态调度一个像 Kubernetes 一样的编排器。服务间通信不仅异常复杂,而且也是运行时行为的基础。管理好服务间通信对于保证端到端的性能和可靠性来说是非常重要的。

Service Mesh 是一种网络模型吗?

Service Mesh 是位于 TCP / IP 之上的抽象层的网络模型。 它假设底层的 L3 / L4 网络存在并且能够从点到点传送字节。(它也假定这个网络和环境的其他方面一样是不可靠的;因此 Service Mesh 也必须具备处理网络故障的能力)。

在某些方面,Service Mesh 有点类似 TCP/IP。TCP 对网络端点间传输字节的机制进行了抽象,而 Service Mesh 则是对服务节点间请求的路由机制进行了抽象。

像 TCP 一样,Service Mesh 不关心实际的有效载荷或者它的编码方式。应用程序的目标是“将某些东西从 A 传送到 B”,而 Service Mesh 所要做的就是实现这个目标,并处理传送过程中可能出现的任何故障。

与 TCP 不同的是,Service Mesh 有着超越“只是能工作”的更高的目标:为应用运行时提供统一的、应用层面的可见性和可控性。Service Mesh 的明确目标是将服务通信从隐形的,隐含的基础设施的领域转移到生态系统的一流成员的角色中,在那里它可以被监控,管理和控制。

Service Mesh 可以做什么?

在云本地应用程序中可靠地传送请求可能非常复杂。像 Linkerd 这样的 Service Mesh 通过一系列强大的技术来管理这种复杂性:电路中断,延迟感知、负载平衡,最终一致性服务发现,重试和超时。 这些功能必须全部配合使用,这些功能与其运行的复杂环境之间的交互可能非常微妙。

例如,当通过 Linkerd 向服务请求时,会发生如下的一系列事件:

1、Linkerd 根据动态路由规则确定请求是发给哪个服务的,比如是发给生产环境里的服务还是发给 staging 环境里的服务?是发给本地数据中心的服务还是发给云端的服务?是发给最新版本的服务还是发给旧版本的服务?这些路由规则可以动态配置,可以应用在全局的流量上,也可以应用在部分流量上。

2、在确定了请求的目标服务后,Linkerd 从服务发现端点获取相应的服务实例。如果服务实例的信息出现了偏差,Linkerd 需要决定哪个信息来源更值得信任。

3、Linkerd 基于某些因素(比如最近处理请求的延迟情况)选择更有可能快速返回响应的实例。

4、Linkerd 向选中的实例发送请求,并把延迟情况和响应类型记录下来。

5、如果选中的实例发生宕机、没有响应或无法处理请求,Linkerd 就把请求发给另一个实例(前提是请求必须是幂等的)。

6、如果一个实例持续返回错误,Linkerd 就会将其从负载均衡池中移除,并在稍后定时重试(例如这个实例有可能只是临时发生故障)。

7、如果请求超时,Linkerd 会主动放弃请求,不会进行额外的重试。

8、Linkerd 以度量和分布式跟踪的形式捕捉上述行为的每一个方面,并将其发送到集中的度量系统。

除此之外,这只是简化的版本,Linkerd 还能启动和终止 TLS、执行协议升级、动态调整流量、在数据中心之间进行故障切换。

下一代微服务架构——Service Mesh_第1张图片

Linkerd 的这些特性可以保证局部的弹性和应用层面的弹性。大规模分布式系统有一个共性:局部故障累积到一定程度就会造成系统层面的灾难。Service Mesh 的作用就是在底层系统的负载达到上限之前通过分散流量和快速失效来防止这些故障破坏到整个系统。

为什么我们需要 Service Mesh?

Service Mesh 并非新出现的功能。Web 应用程序一直需要自己管理复杂的服务间通信, Service Mesh 的起源可以追溯到过去十五年来这些应用的发展。

2000 年左右的中型 Web 应用一般使用了三层模型:应用逻辑层、Web 服务逻辑层和存储逻辑层。层与层之间的交互虽然复杂,但范围有限,毕竟一个请求最多只需要两个跳转。虽然这里不存在“网格”,但仍然存在跳转通信逻辑。

随着规模的增长,这种架构就显得力不从心了。像 Google、Netflix、Twitter 这样的公司面临着大规模流量的需求,他们实现了云原生应用的前身:应用层被拆分为多个服务(也叫作微服务),层级成了一种拓扑结构。这样的系统需要一个通用的通信层,以一个“富客户端”包的形式存在,如 Twitter 的 Finagle、Netflix 的 Hystrix 和 Google 的 Stubby。

在许多方面,像 Finagle、Stubby 和 Hystrix 这样的包就是最初的 Service Mesh。

虽然他们特定于周围环境的细节,并要求使用特定的语言和框架,但它们是用于管理服务对服务通信的专用基础架构的形式,(对于开源的 Finagle 和 Hysterix 库 )在其原籍公司之外使用。

快速转到现代云原生应用程序。 云原生模式将许多小型服务的微服务方法与另外两个因素相结合:容器(例如,提供资源隔离和依赖管理的 Docker),以及将底层硬件抽象为同质池的编排层(例如 Kubernetes)。

这三个组件允许具有自然机制的应用程序在负载下进行缩放,并处理云环境的永久存在的局部故障。 但是,数百个服务或数千个服务,以及一个不时重新调度实例的编排层,单个请求通过服务拓扑所遵循的路径可能非常复杂,并且由于容器使得每个服务都可以很容易地写入 用不同的语言,之前的方法已经不再可行了。

这种复杂性和重要性的结合激发了对与应用程序代码分离的服务到服务通信的专用层的需求,并且能够捕获底层环境的高度动态性质。 这一层是 Service Mesh。

Service Mesh 的未来

虽然云原生生态系统中 Service Mesh 的采用正在迅速增长,但是还有一个广泛而令人兴奋的发展路线值得探索。 对无服务器计算(例如 Amazon 的 Lambda)的要求直接适用于 Service Mesh 的命名和链接模型,并形成其在云原生生态系统中的角色的自然延伸。 服务标识和访问策略在云原生环境中的作用仍然很新颖,Service Mesh 在这里扮演着重要角色。 最后,像之前的 TCP / IP 这样的服务 Service Mesh 继续被推进到底层基础架构中。 就像 Linkerd 从 Finagle 这样的系统发展而来,作为单独的用户空间代理的服务的当前版本必须明确地添加到云原生堆栈中,这个代理也将继续发展。

结论

Service Mesh 是云原生技术栈中一个非常关键的组件。Linkerd 项目在启动一年多之后正式成为 CNCF 的官方项目,并拥有了众多的贡献者和用户。Linkerd 的用户横跨初创公司(如 Monzo)到大规模的互联网公司(如 PayPal、Ticketmaster、Credit Karma),再到拥有数百年历史的老牌公司(如 Houghton Mifflin Harcourt)。

原文地址:https://www.tuicool.com/articles/uQFbYzB

作者: 王志宇

JFrog 中国研发工程师,曾在唯品会担任研发工程师,擅长Java,参与过多个互联网平台的研发和运维工作,现专注于Devops 落地,持续集成、持续交付领域。

欢迎转载,但转载请注明作者与出处。谢谢!