Fallacies of Distributed Computing Explained:
为啥会有这些明显不现实的悖论呢?因为我们开发人员就是这样很少考虑网络问题,这都是我们对网络的极度幻想!
服务发现(Service discovery )是自动找到满足给定查询请求的服务实例的过程。例如名为Teams的服务需要查找将属性环境设置为生产的名为Players的服务的实例。您将调用一些服务发现过程,该过程将返回合适的服务器列表。对于更多的整体架构,这是一个简单的任务,通常使用DNS,负载均衡器以及一些关于端口号的约定来实现(例如,所有服务将其HTTP服务器绑定到端口8080)。 在更加分散的环境中,任务开始变得越来越复杂,以前可以盲目地依靠其DNS查找来找到依赖关系的服务现在必须处理诸如客户端负载平衡,多个不同环境(例如,登台与生产) ),地理位置分散的服务器等。如果之前只需要一行代码来解析主机名,那么现在您的服务就需要很多样板代码来处理更高版本所带来的各种情况。
断路器是Michael Nygard在他的书Release It中分类的一种模式。Martin Fowler对该模式的总结:
断路器的基本原理非常简单。将受保护的方法调用包装在断路器对象,该对象将监视故障。一旦故障达到阈值,断路器将跳闸,并且所有对该断路器的进一步调用都会返回错误,而根本不会进行受保护的调用。通常,如果断路器跳闸,您还需要某种监视器警报。
这些非常简单的设备可为你的服务之间的交互增加更多的可靠性。但随分布水平提高,它们往往会变得更加复杂。系统中出现问题的可能性随着分布的增加而呈指数级增长,因此,即使诸如“断路器跳闸时出现某种监视器警报”之类的简单事情也不一定变得简单明了。一个组件中的一个故障会在许多客户端和客户端的客户端之间造成一连串的影响,从而触发数千个电路同时跳闸。过去仅需几行代码,现在又需要样板代码来处理仅在这个新世界中存在的情况。
实际上,上面列出的两个示例很难正确实现,以至于大型,复杂的库(如Twitter的Finagle和Facebook的Proxygen)非常受欢迎,因为它避免在每个服务中重写相同逻辑。
该模型被大多数开创了微服务架构的组织所采用,例如Netflix,Twitter和SoundCloud。
但随着系统中服务数量的增加,发现了此模型的
与我们在网络栈中看到的类似,非常需要将大规模分布式服务所需的功能提取到基础平台中。
人们使用HTTP等高级协议编写应用程序和服务,而无需考虑TCP如何控制其网络上的数据包。这种情况正是微服务所需要的,工程师可以专注业务逻辑,避免浪费时间编写自己的服务基础结构代码或管理整个团队中的库和框架。
不幸的是,更改网络栈以添加此层并不可行。
许多从业人员发现的解决方案是将其作为一组代理来实现。即服务不会直接连接到其下游依赖,而是所有流量都将通过一小段软件透明地添加所需的功能。
在该领域中最早记录在案的发展使用了sidecar的概念。sidecar是在你的应用旁边运行并为其提供附加功能的辅助进程。 2013年,Airbnb撰写了有关Synapse和Nerve的开源文件,其中包括Sidecar的开源实现。一年后,Netflix推出了Prana,这是一种辅助工具,致力于允许非JVM应用程序从其NetflixOSS生态系统中受益。
其实这种模式很早就出现了,比如 k8s 的 pod部署多个容器,其一就是处理日志的filebeat,其本质就是个 sidecar,只不过我们一般都是部署一个处理网络请求的 sidecar。 至此,已经很接近 service mesh 了。
尽管有许多此类开源代理实现,但它们往往旨在与特定的基础结构组件一起使用。例如服务发现,Airbnb的Nerve&Synapse假定服务已在Zookeeper中注册,而对于Prana,则应使用Netflix自己的Eureka服务注册表。
随着微服务架构的日益普及,我们最近看到了新一轮的代理浪潮,这些代理足够灵活以适应不同的基础架构组件和偏好。这个领域的第一个广为人知的系统是Linkerd,它是由Buoyant根据工程师在Twitter微服务平台上的先前工作创建的。很快,Lyft的工程团队发布了Envoy,它遵循类似的原则。
在这种模型中,你的每个服务都将有一个伴随代理服务。鉴于服务仅通过Sidecar代理相互通信,因此我们最终得到了类似于下图的部署,可以说就是 sidecar 的网络拓扑组合。
Buoyant的CEO William Morgan 指出,代理之间的互连形成了网状网络(mesh network)。 2017年初,William为该平台编写了一个定义,并将其称为Service Mesh: 服务网格是用于处理服务到服务之间通信的基础设施层。它主要负责在现代的云原生应用这种复杂的服务拓扑场景下,进行可靠地请求分发。实际上,它通常被实现为一组轻量级的网络代理,部署在你的应用代码旁边,并且对你的应用程序完全透明。
他的定义中最有力的方面可能是,它摆脱了将代理视为独立组件的想法,并认识到它们形成的网络本身就是有价值的东西。
随着人们将其微服务部署移至更复杂的运行时(如Kubernetes和Mesos),人们已开始使用这些平台提供的工具来正确实现网状网络的想法。他们正从一组独立工作的独立代理转移到一个适当的,集中式的控制平面。
纵观我们的鸟瞰图,我们看到实际的服务流量仍然直接从代理流向代理,但是控制平面知道每个代理实例。控制平面使代理可以实现访问控制和指标收集之类的事情,这需要合作:
最近开源的Istio项目是此类系统的最突出示例。
路由: 蓝绿部署 灰度发布 A/B测试
流量转移 超时重试 熔断 故障注入 流量镜像
流量控制 黑白名单
授权及身份认证
指标收集和展示 日志收集 分布式追踪
负责容器编排调度,本质是管理应用的生命周期,即调度器。给予Service Mesh支持和帮助,因为其 pod 是最小的调度单元,先天支持多容器的部署,便于植入 sidecar 服务。
解决服务间网络通信问题,本质上是管理服务通信,即代理。是对 k8s 网络功能方面的扩展延伸
API网关有负载均衡、服务发现、流量控制等作用。
所以综合来看,功能有重叠,但角色不同。Service Mesh在应用内,API网关在应用之上(边界)。
统一数据平面 API,为不同的数据平面提供统一的 API,方便你的无缝接入,比如 Envoy、Linkerd等数据平面。有了 UDPA 就无需关心他们的实现细节,按标准接入即可。 该标准由云原生基金会提出。
侧重于数据控制平面,为用户提供一个统一的使用体验。 你也发现了,Google 和 aws 并没有参与。
第一个Service Mesh产品 2016年底在GitHub发布 0x 2017年加入CNCF,4月发布1.0版本 Conduit - Linkerd2.0: 支持 k8s,轻量级,但是用的 rust,没人会,没人用,无疾而终。
2016年9月发布,定位Sidecar代理,第3个从CNCF毕业的产品。 稳定可靠,性能出众,Istio的默认数据平面,xDS协议成为数据平面的事实标准。
2017年5月发布0.1版本,主角光环:Google, IBM,Lyft 背书。第二代Service Mesh,增加了控制平面,奠定目前Service Mesh的产品形态。 收购Envoy,直接拥有高水准的数据平面,受到社区强烈追捧。
全面理解ServiceMesh在大规模系统中的影响还为时过早。总之这种方法有两个好处
参考