Netflix 零配置服务网格与按需集群发现

本文翻译自由 David Vroom, James Mulcahy, Ling Yuan, Rob Gulewich 编写的 Netflix 博客 Zero Configuration Service Mesh with On-Demand Cluster Discovery。

Netflix 相信大家并不陌生,在 Spring Cloud 生态中就有 Netflix 全家桶。多年前,我也曾将基于 Netflix OSS 构建的微服务架构搬上了 Kubernetes 平台,并持续折腾好几年。

Spring Cloud Netflix 有着庞大的用户群以及用户场景,其提供了微服务治理的一整套解决方案:服务发现 Eureka、客户端负载均衡 Ribbon、断路器 Hystrix、微服务网格 Zuul。

有过相同经历的小伙伴应该都会同感,这样一套微服务解决方案的架构,经过多年的演进也会让人痛苦不堪:复杂度越来越高、版本碎片化严重、多语言多框架的支持和功能无法统一等等。这也是 Netflix 自己也不得不面对的问题,随后他们将目光转向了服务网格,并寻求一个无缝迁移的方案。

这篇文章中,他们给出了答案:Netflix 与社区合作,并自建控制平面与已有的服务发现体系兼容。这套实现下来可能并不容易,也未看到他们要将其开源的想法,但是至少可以给大家一个参考。

顺便预告一下自己正在计划的一篇,如何将微服务平滑迁移到 Flomesh 服务网格平台。不止无缝兼容 Eureka,还有 HashiCorp Consul,未来还会兼容更多的服务发现方案。

以下是原文的翻译:


在这篇文章中,我们将讨论 Netflix 服务网格(Service Mesh)实践的相关信息:历史背景、动机,以及我们如何与 Kinvolk 和 Envoy 社区合作,在复杂的微服务环境中推动服务网格落地的一个特征:按需集群发现(On-demand Cluster Discovery)。

Netflix 的 IPC 简史

Netflix 是早期云计算的采纳者,特别是对于大规模的公司:我们在 2008 年开始了迁移,并且到 2010 年,Netflix的流媒体完全运行在AWS上。今天我们拥有丰富的工具,包括开源和商业的,所有这些都是为云原生环境设计的。然而,在 2010 年,几乎没有这样的工具存在:CNCF 直到 2015 年才成立!由于没有现成的解决方案,我们需要自己构建它们。

对于服务间的进程间通信(IPC),我们需要一个中间层负载均衡器通常提供的丰富功能集。我们还需要一种解决方案,来应对云环境的现实:一个高度动态的环境,其中节点不断上线和下线,服务需要快速响应变化并隔离失败。为了提高可用性,我们设计了可以单独发生故障的系统组件,以避免单点故障。这些设计原则引导我们走向了客户端负载均衡,而 2012年圣诞节的宕机 进一步坚定了这个决策。在云早期,我们构建了Eureka 用于服务发现,以及 Ribbon(内部名为NIWS)用于IPC。Eureka 解决了服务如何发现与其通信的实例的问题,而 Ribbon 提供了负载均衡的客户端,以及许多其他的弹性特性。这两项技术,加上一系列其他的弹性和混沌工具,产生了巨大的收益:我们的可靠性因此得到了显著的改善。

Eureka 和 Ribbon 提供了一个简单而强大的接口,让它们的使用变得容易。一个服务与另一个服务通信,需要知道两件事:目的服务的名称,以及流量是否应该是安全的。Eureka 为此提供的抽象是虚拟 IP(VIPs)用于非安全通信,和安全 VIPs(SVIPs)用于安全通信。服务向 Eureka 宣布一个 VIP 名和端口(例如:_myservice_,端口 _8080_),或一个 SVIP 名和端口(例如:_myservice-secure_,端口 8443),或同时使用两者。IPC 客户端针对该 VIP 或 SVIP 进行实例化,而 Eureka 客户端代码通过从 Eureka 服务器获取它们来处理该 VIP 到一组 IP 和端口对的转换。客户端还可以选择启用像重试或熔断这样的 IPC 功能,或者使用一组合理的默认值。

在这种架构中,服务间通信不再通过负载均衡器的单点故障通道。但问题是,Eureka 现在成为了 VIP 注册主机真实性的新的单一故障点。然而,如果 Eureka 宕机,服务仍然可以互相通信,尽管它们的主机信息随着 VIP 的上下线而逐渐过时。在故障期间以降级但可用的状态运行仍然是相比完全停止流量的明显改进。

在这种架构中,服务与服务间的通信不再经过负载均衡器的单一故障点。但问题是,Eureka 现在成为了 VIP 注册主机真实性的新的单一故障点。然而,如果 Eureka 宕机,服务仍然可以互相通信,尽管它们的主机信息随着 VIP 的上下线而逐渐过时。在故障期间以降级但可用的状态运行仍然是相比完全停止流量的明显改进。

为什么选择网格?

上述架构在过去的十年里为我们服务得很好,但随着业务需求的变化和行业标准的演变,我们的 IPC 生态系统在很多方面都增加了更多的复杂性。首先,我们增加了不同的 IPC 客户端的数量。我们的内部 IPC 流量现在是纯 REST、GraphQL 和 gRPC 的混合。其次,我们从只使用 Java 环境迁移到了多语言环境:我们现在也支持 node.js、Python 以及各种开源和现成的软件。第三,我们继续为 IPC 客户端增加更多功能,如 自适应并发限制、断路器、对冲和故障注入已成为我们工程师为使系统更可靠而采用的标准工具。与十年前相比,我们现在支持更多功能、更多语言、更多客户端。确保所有这些实现之间的功能一致性并确保它们都以相同的方式运行是具有挑战性的:我们希望这些功能有一个单一、经过充分测试的实现,这样我们可以在一个地方进行更改和修复错误。

这就是服务网格的价值所在:我们可以在一个实现中集中 IPC 功能,并使每种语言的客户端尽可能简单:它们只需要知道如何与本地代理通话。Envoy 对我们来说是代理的绝佳选择:它是一个经过战斗考验的开源产品,已经在行业中被广泛使用,拥有 许多关键的弹性功能,以及当我们需要扩展其功能时的 良好的扩展点。能够 通过一个集中的控制平面配置代理 是一个杀手级的功能:这使我们可以动态配置客户端负载均衡,就像它是一个集中的负载均衡器,但仍然避免了服务到服务请求路径中的负载均衡器作为单一的故障点。

转向服务网格

一旦认定我们决定转向服务网格是正确的选择,下一个问题便是:我们应如何进行迁移?我们确定了一些迁移的限制条件。首先:我们希望保留现有的接口。通过指定 VIP 名称加上安全服务的抽象为我们提供了良好服务,我们不想破坏向后兼容性。其次:我们希望自动化迁移,并使其尽可能无缝。这两个限制意味着我们需要支持 Envoy 中的 Discovery 抽象,以便 IPC 客户端可以继续在底层使用它。幸运的是,Envoy 已经有了 现成的抽象 可以用。VIP 可以表示为 Envoy 集群,代理可以从我们的控制平面使用集群发现服务 (CDS) 获取它们。这些集群中的主机表示为 Envoy 端点,可以使用端点发现服务 (EDS) 获取。

我们很快遇到了一个无缝迁移的障碍:Envoy 要求在代理的配置中指定集群。如果服务 A 需要与集群 B 和 C 通信,那么需要在 A 的代理配置中定义集群 B 和 C。这在规模上可能具有挑战性:任何给定的服务可能会与数十个集群通信,而每个应用程序的集群集合都是不同的。此外,Netflix 始终在变化:我们不断推出新的项目,如直播、广告 和游戏,并且不断发展我们的架构。这意味着服务通信的集群会随着时间的推移而改变。鉴于我们可用的 Envoy 原语,我们评估了一些填充集群配置的不同方法:

  1. 让服务所有者定义他们的服务需要与之通信的集群。这个选项看似简单,但实际上,服务所有者并不总是知道,或想要知道,他们与哪些服务通信。服务通常会导入由其他团队提供的库,这些库在底层与多个其他服务通信,或与像遥测和日志记录等其他操作服务通信。这意味着服务所有者需要知道这些辅助服务和库是如何在底层实现的,并在它们发生变化时调整配置。
  2. 根据服务的调用图自动生成 Envoy 配置。这种方法对于预先存在的服务来说很简单,但是在启动新服务或添加新的上游集群以进行通信时具有挑战性。
  3. 将所有集群推送到每个应用程序:这个选项以其简单性吸引了我们,但是纸巾上的简单计算很快向我们显示,将数百万个端点推送到每个代理是不可行的。

考虑到我们无缝采纳的目标,每个选项都有足够重大的缺点,使我们探索了另一个选项:如果我们能在运行时按需获取集群信息,而不是预先定义它,会怎样?当时,服务网格工作仍在启动阶段,只有少数几个工程师在致力于它。我们联系了 Kinvolk,看看他们是否能与我们和 Envoy 社区合作实施这个功能。这次合作的结果是 按需集群发现(On-Demand Cluster Discovery,ODCDS)。有了这个功能,代理现在可以在第一次尝试连接它时查找集群信息,而不是在配置中预先定义所有集群。

有了这个功能,我们需要给代理提供集群信息以供查询。我们已经开发了一个实现 Envoy XDS 服务的服务网格控制平面。然后我们需要从 Eureka 获取服务信息以返回给代理。我们将 Eureka 的 VIP 和 SVIP 表示为单独的 Envoy Cluster Discovery Service (CDS) 集群(因此,服务 myservice 可能有集群 myservice.vip 和 _myservice.svip_)。集群中的单个主机被表示为单独的 Endpoint Discovery Service (EDS) 端点。这使得我们能够重复使用相同的 Eureka 抽象,并且像 Ribbon 这样的 IPC 客户端可以通过最小的更改转移到网格。控制平面和数据平面的更改到位后,流程如下所示:

  1. 客户端请求进入 Envoy。
  2. 根据 Host / :authority 头(此处使用的头可配置,但这是我们的方法)提取目标集群。如果已知该集群,跳到步骤 7。
  3. 集群不存在,所以我们暂停了正在传输的请求。
  4. 向控制平面的 Cluster Discovery Service (CDS) 端点发出请求。控制平面根据服务的配置和 Eureka 注册信息生成定制的 CDS 响应。
  5. Envoy 获取集群(CDS),触发通过 Endpoint Discovery Service (EDS) 拉取端点。根据该 VIP 或 SVIP 的 Eureka 状态信息返回集群的端点。
  6. 客户端请求解除暂停。
  7. Envoy 正常处理请求:它使用负载平衡算法选择一个端点并发出请求。

这个流程在几毫秒内完成,但只在对集群的第一次请求时。之后,Envoy 的行为就好像集群是在配置中定义的一样。关键是,该系统允许我们无需任何配置即可无缝迁移服务至服务网格,满足我们的主要采纳限制之一。我们呈现的抽象继续是 VIP 名称加上安全,并且我们可以通过配置单个 IPC 客户端连接到本地代理而不是直接连接到上游应用程序来迁移到网格。我们继续使用 Eureka 作为 VIP 和实例状态的真实来源,这使得我们能够在迁移时支持一些应用程序在网格上,而另一些不在网格上的异构环境。还有一个额外的好处:我们可以通过仅为我们实际通信的集群获取数据来保持 Envoy 的内存使用率较低。

上图展示了一个 Java 应用中的 IPC 客户端通过 Envoy 与注册为 SVIP A 的主机通信。 Envoy 从网格控制平面获取 SVIP A 的集群和端点信息。网格控制平面从 Eureka 获取主机信息。

按需获取此数据的缺点是:这会增加对集群的第一次请求的延迟。我们遇到了服务在第一次请求时需要非常低延迟访问的用例,并且增加了几毫秒额外的开销。对于这些用例,服务需要预定义它们通信的集群,或在第一次请求之前准备好连接。我们还考虑过根据历史请求模式在代理启动时从控制平面预推送集群。总的来说,我们觉得系统中的降低的复杂性证明了对少量服务的缺点是合理的。

我们在服务网格之旅的初期。现在我们真诚地使用它,我们希望与社区合作做出更多的 Envoy 改进。将我们的 自适应并发限制 实现移植到 Envoy 是一个很好的开始 - 我们期待着与社区在更多方面合作。我们特别对社区在增量 EDS 方面的工作感兴趣。EDS 端点占了更新量的最大部分,这对控制平面和 Envoy 造成了不必要的压力。

我们要非常感谢 Kinvolk 的人员对 Envoy 的贡献:Alban Crequy, Andrew Randall, Danielle Tal, 特别是 Krzesimir Nowak 的出色工作。我们也要感谢 Envoy 社区的支持和锋利的审查:Adi Peleg, Dmitri Dolguikh, Harvey Tuch, Matt Klein, 和 Mark Roth。与你们所有人合作是一次很好的经历。

这是我们通向服务网格之旅的系列文章的第一篇,敬请期待。

关注"云原生指北"微信公众号 (转载本站文章请注明作者和出处乱世浮生,请勿用于任何商业用途)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/141707.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【计算机网络】——数据链路层(应用:介质访问控制)

//仅做个人复习和技术交流,图片取自王道考研,侵删 一、大纲 1、介质访问控制 信道划分介质访问控制 随机访问介质访问控制 2、局域网 3、广域网 4、数据链路层设备 二、介质访问控制 省流:把广播信道通过介质访问控制机制 逻辑上转换为 …

C#里面的三种定时计时器:Timer

在.NET中有三种计时器: 1、System.Windows.Forms命名空间下的Timer控件,它直接继承自Componet。Timer控件只有绑定了Tick事件和设置EnabledTrue后才会自动计时,停止计时可以用Stop()方法控制,通过Stop()停止之后,如果想…

vue点击pdf文件直接在浏览器中预览文件

好久没有更新文章了,说说为什么会有这篇文章呢,其实是应某个热线评论的要求出的,不过由于最近很长一段时间没打开csdn现在才看到,所以才会导致到现在才出。 先来看看封装完这个预览方法的使用,主打一个方便使用&#x…

MySQL - 关于约束类型和作用的介绍

约束的概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据。 约束的作用:用于保证数据库中数据的正确性、完整性和一致性。 约束分类: 约束类型作用关键字非空约束限制该字段的数据不能为nullnot null唯一约束保证该…

网络编程-TCP协议(客户端和服务端)

需要了解UDP协议的,可以看往期文章 https://flypeppa.blog.csdn.net/article/details/133273416 TCP/IP参考模型 代码案例 服务端代码 package com.hidata.devops.paas.udp;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStr…

使用Jaeger进行分布式跟踪:学习如何在服务网格中使用Jaeger来监控和分析请求的跟踪信息

🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…

硬件基本功--MOS管

一、上下拉电阻Rgs的作用 Rgs:经验值,一般取10K左右。 1. 上电时给MOS管的栅极一个确定的电平,防止上电时GPIO为高阻态时,MOS管的栅极电平不确定,从而受到干扰。 2. 断电时,如果MOS管是导通的状态&#xff…

什么是 Redis?

Redis 是一种基于内存的数据库,对数据的读写操作都是在内存中完成的,因此读写速度非常快,常用于缓存,消息队列,分布式锁等场景。 Redis 提供了多种数据类型来支持不同的业务场景,比如 String(字符串)、Has…

基于springboot+vue的大学生创新创业系统(前后端分离)

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

【Vue】Mock.js介绍和使用与首页导航栏左侧菜单搭建

目录 一、Mock.js 1.1 mockjs介绍 1.2 mock.js安装与配置 1.2.1 安装mock.js 1.2.2 引入mock.js 1.3 mock.js的使用 1.3.1 准备模拟数据 1.3.2 定义拦截路由 1.3.3 测试 二、首页导航栏左侧菜单搭建 2.1 自定义界面组件 (完整代码) 2.2 配置路由 2.3 组件显示折叠和…

矿山定位系统-矿井人员定位系统在矿山自动化安全监控过程中的应用

一,矿井人员定位系统现阶段使用的必要性 1,煤矿开采是一项非常特殊的工作,现场属于非常复杂多变的环境,井下信号极差,数据传输非常不稳定,人员安全难以保证,煤矿企业一直在研究如何使用更合适的…

Linux学习之HIS部署(4)

ElasticSearch部署 ElasticSearch资源 RabbitMQ资源 ElasticSearch服务部署 #OpenJDK环境部署 [rootServices ~]# yum clean all; yum repolist -v ... Total packages: 8,265 [rootServices ~]# yum -y install java-1.8.0-openjdk-devel.x86_64 #安装OpenJDk ... Compl…

什么是LIMS(实验室信息管理系统)?LIMS软件有哪些功能?

LIMS 是实验室信息管理系统(Laboratory Information Management System)的缩写。LIMS 是一种软件,它可以帮助实验室收集、组织和跟踪其数据。这种系统可以提高实验室的效率,同时确保数据的准确性和一致性。 LIMS 可以处理各种实验…

centos7用docker安装WireGuard教程

1、 检查centos内核版本 uname -r2、升级内核 下载脚本上传到服务器运行脚本进行升级内核 链接:https://pan.baidu.com/s/1vYmqVy2St3nFnJWGPIwdOw 提取码:owac 3、安装WireGuard 方案一:使用脚本安装 执行第二步脚本进行安装#启动wg0wg…

go-redis 框架基本使用

文章目录 redis使用场景下载框架和连接redis1. 安装go-redis2. 连接redis 字符串操作有序集合操作流水线事务1. 普通事务2. Watch redis使用场景 缓存系统,减轻主数据库(MySQL)的压力。计数场景,比如微博、抖音中的关注数和粉丝数…

xss原理分析

插入法,弹窗法,事件法 绕过HttpOnly通过找到phpinfo的方式,可以看到cookie

新版收款码三合一在线生成系统源码

收款码三合一这个概念相信大家很多人都已经听说过了,而且大家在很多场景也见过商家们已经开始使用这样的收款码了, 前台放着一个二维码,上边写着“支付宝、微信、QQ扫码付款”不管你用哪个软件扫码,都能正确识别,但是…

SpringCloud 学习(四)Hystrix

6. Netflix.Hystrix 6.1 简介 ● 扇出 多服务之间调用,若微服务 A 调用微服务 B 和微服务 C,微服务 B 和 微服务 C 又调用其他微服务,这就是扇出 ● 服务雪崩 若扇出的链路上某个微服务的调用响应时间过长或者不可用,么此扇出…

人工智能AI 全栈体系(六)

第一章 神经网络是如何实现的 这些年神经网络的发展越来越复杂,应用领域越来越广,性能也越来越好,但是训练方法还是依靠 BP 算法。也有一些对 BP 算法的改进算法,但是大体思路基本是一样的,只是对 BP 算法个别地方的一…

ADC数模转化器

简介 • ADC ( Analog-Digital Converter )模拟 - 数字转换器 • ADC 可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁 • 12 位逐次逼近型 ADC , 1us 转换时间 (12位:分辨率…