在过去的一年中,服务网格(Service Mesh)已经演变成为云原生堆栈的重要组成部分。像 Paypal,Lyft,Ticketmaster 和 CreditKarma 这样的高流量公司都已经为其生产应用添加了 ServiceMesh。并且,今年1月,用于云原生应用的开源 ServiceMesh-Linkerd 成了为 CNCF 的官方项目。但是到底什么是 ServiceMesh 呢?为什么突然受到关注?
在本文中,我将给给出 ServiceMesh 的定义,通过分析在过去十年中应用架构的变迁来追踪分析它的变化。同时,我也会区分 ServiceMesh 与之相关但不同的概念,包括 API 网关,EdgeProxies(边缘代理)和 ESB(企业服务总线)。最后,我将介绍 ServiceMesh 的发展方向,以及分写随着云原生应用的发展,这个概念将会发生什么变化。
ServiceMesh 是用于处理服务到服务通信的专用基础设施层,它负责为现代云原生应用的复杂服务拓扑可靠地传递请求。
在实践中,ServiceMesh 通常被实现为与应用程序代码一起部署的轻量级网络代理数组,而应用程序不需要知道它的存在(但是外界也存在不同的看法)。
ServiceMesh 作为单独层的概念与云原生应用的兴起有关。在云原生模型中,单个应用程序可能包含数百个服务;每个服务可能有数千个实例;并且这些实例中的每一个都可能处于不断变化的状态,因为它们是使用诸如 Kubernetes 之类的编排器动态地调度的。
世界上的服务交流不仅非常复杂,同时也是运行时行为的基本组成部分。合理管理使用 ServiceMesh,对于确保端到端的性能和可靠性至关重要。
ServiceMesh 是一个网络模型,它位于 TCP/IP 以上的抽象层。它假设底层的L3/L4网络是存在的,并能够从点到点传送字节(它还假设这个网络与环境的其他方面一样是不可靠的,因此,ServiceMesh 也必须能够处理网络故障)。
在某些方面,ServiceMesh 类似于 TCP/IP。正如 TCP 栈抽象出在网络端点之间可靠传递字节的机制,ServiceMesh 抽象了在服务之间可靠地传递请求的机制。
像 TCP 一样,ServiceMesh 不关心实际的有效载荷或它的编码方式。应用程序具有高级目标(“从A发送到B”),并且 ServiceMesh 的工作(如TCP)是在处理过程中发生任何故障时完成此目标。
与 TCP 不同,ServiceMesh 具有超越“仅仅使其工作”的重要目标:它提供了统一的应用范围点,用于将可视性和控制引入运行时的应用程序。ServiceMesh 的明确目标是将服务通信从不可见,隐含的基础设施领域转移为生态系统的一等公民———可以在其中进行监控,管理和控制。
在云原生应用中可靠地传递请求可能非常复杂。像 Linkerd 这样的 ServiceMesh 可以通过各种强大的技术来管理这种复杂性:断电,延迟感知负载平衡,最终一致性(“咨询”)服务发现,重试和最后期限。这些功能必须一起工作,并且这些功能之间的相互作用以及它们运行的复杂环境可能相当微妙。
例如,当通过 Linkerd 向服务发出请求时,简化的事件时间表如下:
当然,这只是简化版本,Linkerd 还可以发起和终止 TLS,执行协议升级,动态转移流量,并在数据中心之间进行故障转移!
要注意这些功能旨在提供点向弹性和应用范围的弹性。大型分布式系统无论其架构如何,都具有一个典型的特征:它们为小型本地化故障提供了许多机会,从而可能演变为全系统的灾难性故障。ServiceMesh 必须设计为通过减少负载来防止这些恶性演变,并在底层系统接近其极限时让其快速失败。
ServiceMesh 并不是一项新的功能,而是功能位置的转变。Web 应用程序一直不得不管理服务通信的复杂性,ServiceMesh 模型的起源可以追溯到过去十五年来这些应用的发展。
考虑2000年时中型 Web 应用程序的典型架构:三层应用程序。在这个模型中,应用程序逻辑,Web 服务逻辑和存储逻辑都是一个单独的层。层之间的沟通虽然复杂,但范围有限———毕竟只有两跳。没有“Mesh”,但是在每层的代码之间处理跳数有通信逻辑。
当这种架构方式被推到扩展性非常高的场景时,它开始破裂了。像 Google,Netflix 和 Twitter 这样的公司面临着巨大的流量需求,实现了云原生方案的前身:应用层被分解为许多服务(有时称为“微服务”),层级成为拓扑。在这些系统中,广义通信层变得强相关,但通常采用“胖客户端”的形式-Twitter 的 Finagle,Netflix 的 Hysterix 和 Google 的 Stubby 就是这样的例子。
在许多方面,像 Finagle,Stubby 和 Hysterix 这样的库是第一个 ServiceMesh。虽然它们与具体周围环境的细节相关,并且需要使用特定的语言和框架,但它们是用于管理服务到服务通信的专用基础设施,并且(在开源 Finagle 和 Hysterix 库的情况下)可以在其公司之外使用。
快进到现代云原生应用。云原生模型将许多小型服务的微服务方法与两个额外的因素相结合:容器(例如,提供资源隔离和依赖关系管理的 Docker)和编排层(例如 Kubernetes),将底层硬件抽象为同质池。
这三个组件允许具有自然机制的应用程序在负载下进行扩展,并能够处理云环境中存在的部分故障。
但是,随着数百个服务或数千个服务,以及随时重新安排实例的业务流程层,通过服务拓扑获得单一请求的路径可能非常复杂,并且由于容器使得用不同的语言实现服务变得容易,库的方法已经不再可行了。
这种复杂性和关键性的组合促使需要产生专用层,用于从应用程序代码中分离出服务到服务的通信,并能够捕获底层环境的高度动态性质。这个层就是 ServiceMesh。
虽然在云原生生态系统中的 ServiceMesh 正在迅速增长,但仍然存在有待探索且令人兴奋的路线图。
无服务计算(例如亚马逊的 Lambda)的要求直接适用于 ServiceMesh 的命名和链接模型,并且是它在云原生生态系统中角色的自然扩展。
服务身份和访问策略的作用在云原生环境中仍然很新鲜,ServiceMesh 在此很好的发挥着重要的作用。
最后,ServiceMesh,如之前的 TCP/IP,将继续被推进到底层基础设施中。正如 Linkerd 从 Finagle 这样的系统中演进而来,当前的服务形式作为必须明确添加到云原生堆栈中的单独的用户空间代理,也将继续发展。
ServiceMesh 是云原生堆栈的关键组件。Linkerd 在推出一年多的时间内,就成为了 CNCF 的一部分,拥有广泛的贡献者和用户群体。
其用户包括了 Monzo(英国银行业的颠覆者)到诸如 Paypal,Ticketmaster 和 CreditKarma 这样的大型互联网公司,还有像 HoughtonMifflinHarcourt 这样存在了几百年的公司。