草庐IT

微服务大行其道的今天,Service Mesh是怎样一种存在?

博学谷狂野架构师 2023-03-28 原文

1、Service Mesh简介

1.1、目前微服务架构面临的一些挑战

目前,微服务的架构方式在企业中得到了极大的发展,主要原因是其解决了传统的单体架构中存在的问题。

当单体架构拆分成微服务架构就可以高枕无忧了吗? 显然不是的。

微服务架构体系中同样也存在很多的挑战,比如:

  • 原来的单个应用拆分成了许多分散的微服务,它们之间相互调用才能完成一个任务,而一旦某个过程出错(组件越多,出错的概率也就越大),就非常难以排查。
  • 如果用户请求的响应太慢,我们就需要知道到底哪些地方比较慢?整个链路的调用各阶段耗时是多少?哪些调用是并发执行的,哪些是串行的?这些问题需要我们能非常清楚整个集群的调用以及流量情况。
  • 微服务拆分成这么多组件,如果单个组件出错的概率不变,那么整体有地方出错的概率就会增大。服务调用的时候如果没有错误处理机制,那么会导致非常多的问题。
  • 应用数量的增多,对于日常的应用发布来说也是个难题。应用的发布需要非常谨慎,如果应用都是一次性升级的,出现错误会导致整个线上应用不可用,影响范围太大。
  • 很多情况我们需要同时存在不同的版本,使用 AB 测试验证哪个版本更好。
  • 如果版本升级改动了 API,并且互相有依赖,那么我们还希望能自动地控制发布期间不同版本访问不同的地址。这些问题都需要智能的流量控制机制。
  • 为了保证整个系统的安全性,每个应用都需要实现一套相似的认证、授权、HTTPS、限流等功能。

没错,Service Mesh就是为了解决以上问题才出现的。这就是我们学习本套课程的目的。

1.2、技术架构演进

1.2.1、发展历史时间轴

1.2.2、单机小型机时代

第一个计算机网络诞生于1969年,也就是美军的阿帕网,阿帕网能够实现与其它计算机进行联机操作,但是早期仅仅是为了军事目的而服务
2000年初,中国的网民大约890万,很多人都不知道互联网为何物,因此大多数服务业务单一且简单,采用典型的单机+数据库模式,所有的功能都写在一个应用里并进行集中部署。

说明:论坛业务、聊天室业务、邮箱业务全部都耦合在一台小型机上面,所有的业务数据也都存储在一台数据库上。

1.2.3、垂直拆分

  • 随着应用的日益复杂与多样化,开发者对系统的容灾,伸缩以及业务响应能力有了更高的要求,如果小型机和数据库中任何一个出现故障,整个系统都会崩溃,若某个板块的功能需要更新,那么整个系统都需要重新发布,显然,对于业务迅速发展的万物互联网时代是不允许的。
  • 如何保障可用性的同时快速响应业务的变化,需要将系统进行拆分,将上面的应用拆分出多个子应用。

优点:应用间进行了解耦,系统容错提高了,也解决了独立应用发布的问题。

应用垂直拆分解决了应用发布的问题,但是随着用户数量的增加,单机的计算能力依旧是杯水车薪。

1.2.4、集群化负载均衡架构

用户量越来越大,就意味着需要更多的小型机,但是小型机价格昂贵,操作维护成本高。
此时更优的选择是采用多台PC机部署同一个应用的方案,但是此时就需要对这些应用做负载均衡,因为客户端不知道请求会落到哪一个后端PC应用上的。

负载均衡可以分为硬件层面和软件层面。
硬件层面:F5
软件负载层面:LVS、Nginx、Haproxy
负载均衡的思想:对外暴露一个统一的接口,根据用户的请求进行对应规则转发,同时负载均衡还可以做限流等等

有了负载均衡之后,后端的应用可以根据流量的大小进行动态扩容,我们称为"水平扩展"。

阿里巴巴在2008提出去“IOE”,也就是IBM小型机、Oracle数据库,EMC存储,全部改成集群化负载均衡架构,在2013年支付宝最后一台IBM小型机下线。

优点:通过水平扩展,增强了系统的并发能力。

1.2.5、服务化改造架构

虽然系统经过了垂直拆分,但是拆分之后发现在论坛和聊天室中有重复的功能,比如,用户注册、发邮件等等,一旦项目大了,集群部署多了,这些重复的功能无疑会造成资源浪费,所以会把重复功能抽取出来,名字叫"XX服务(Service)"。

为了解决服务跟服务如何相互调用,需要一个程序之间的通信协议,所以就有了远程过程调用(RPC),作用就是让服务之间的程序调用变得像本地调用一样的简单。

优点:在前面的架构之上解决了业务重用的问题。

1.2.6、服务治理

随着业务的增大,基础服务越来越多,调用网的关系由最初的几个增加到几十上百,造成了调用链路错综复杂,需要对服务进行治理。

服务治理要求:

  • 当我们服务节点数几十上百的时候,需要对服务有动态的感知,引入了注册中心。
  • 当服务链路调用很长的时候如何实现链路的监控。
  • 单个服务的异常,如何能避免整条链路的异常(雪崩),需要考虑熔断、降级、限流。
  • 服务高可用:负载均衡。

典型框架比如有:Dubbo,默认采用的是Zookeeper作为注册中心。

1.2.7、微服务时代

微服务是在2012年提出的概念,微服务的希望的重点是一个服务只负责一个独立的功能。

拆分原则,任何一个需求不会因为发布或者维护而影响到不相关的服务,一切可以做到独立部署运维。

比如传统的“用户中心”服务,对于微服务来说,需要根据业务再次拆分,可能需要拆分成“买家服务”、“卖家服务”、“商家服务”等。

典型代表:Spring Cloud,相对于传统分布式架构,SpringCloud使用的是HTTP作为RPC远程调用,配合上注册中心Eureka和API网关Zuul,可以做到细分内部服务的同时又可以对外暴露统一的接口,让外部对系统内部架构无感,此外Spring Cloud的config组件还可以把配置统一管理。

Spring Cloud微服务架构存在的不足:

  • Spring Cloud属于侵入式框架,在项目中需要添加spring cloud maven依赖,加上spring cloud组件注解,写配置,打成jar的时候还必须要把非业务的代码也要融合在一起。
  • 微服务中的服务支持不同语言开发,也需要维护不同语言和非业务代码的成本;
  • 业务代码开发者应该把更多的精力投入到业务熟悉度上,而不应该是非业务上,Spring Cloud虽然能解决微服务领域的很多问题,但是学习成本还是较大的。
  • 互联网公司产品的版本升级是非常频繁的,为了维护各个版本的兼容性、权限、流量等,因为Spring Cloud是“代码侵入式的框架”,这时候版本的升级就注定要让非业务代码一起,一旦出现问题,再加上多语言之间的调用,工程师会非常痛苦。
  • 我们已经感觉到了,服务拆分的越细,只是感觉上轻量级解耦了,但是维护成本却越高了。

1.2.8、服务网格新时期 (Service Mesh)

Service Mesh主要解决的问题就希望开发人员对于业务的聚焦,服务发现、服务注册、负载均衡等对于开发人员透明,可以更加专注业务逻辑的实现。

如果将为微服务提供通信服务的这部分逻辑从应用程序进程中抽取出来,作为一个单独的进程进行部署,并将其作为服务间的通信代理,可以得到如下图所示的架构:

Sidecar,翻译成中文是边车,非常的形象。

当服务大量部署时,随着服务部署的Sidecar代理之间的连接形成了一个如下图所示的网格,该网格成为了微服务的通讯基础设施层,承载了微服务之间的所有流量,被称之为Service Mesh(服务网格)。

服务网格中有数量众多的Sidecar代理,如果对每个代理分别进行设置,工作量将非常巨大。为了更方便地对服务网格中的代理进行统一集中控制,在服务网格上增加了控制面组件。

1.3、什么是Service Mesh

服务网格用来描述组成这些应用程序的微服务网络以及它们之间的交互。随着服务网格的规模和复杂性不断的增长,它将会变得越来越难以理解和管理。它的需求包括服务发现、负载均衡、故障恢复、度量和监控等。服务网格通常还有更复杂的运维需求,比如 A/B 测试、金丝雀发布、速率限制、访问控制和端到端认证。

1.4、Service Mesh产品

1.4.1、CNCF

CNCF 是一个开源软件基金会,致力于使云原生计算具有普遍性和可持续性。 云原生计算使用开源软件技术栈将应用程序部署为微服务,将每个部分打包到自己的容器中,并动态编排这些容器以优化资源利用率。 云原生技术使软件开发人员能够更快地构建出色的产品。

官网:https://www.cncf.io/

常用的已经毕业的云原生项目:

  • Kubernetes
    • Kubernetes 是世界上最受欢迎的容器编排平台也是第一个 CNCF 项目。 Kubernetes 帮助用户构建、扩展和管理应用程序及其动态生命周期。
  • Prometheus
    • Prometheus 为云原生应用程序提供实时监控、警报包括强大的查询和可视化能力,并与许多流行的开源数据导入、导出工具集成。
  • Jaeger
    • Jaeger 是由 Uber 开发的分布式追踪系统,用于监控其大型微服务环境。 Jaeger 被设计为具有高度可扩展性和可用性,它具有现代 UI,旨在与云原生系统(如 OpenTracing、Kubernetes 和 Prometheus)集成。
  • Envoy
    • Envoy 是最初在 Lyft 创建的 Service Mesh(服务网格),现在用于Google、Apple、Netflix等公司内部。 Envoy 是用 C++ 编写的,旨在最大限度地减少内存和 CPU 占用空间,同时提供诸如负载均衡、网络深度可观察性、微服务环境中的跟踪和数据库活动等功能。
  • Containerd
    • Containerd 是由 Docker 开发并基于 Docker Engine 运行时的行业标准容器运行时组件。 作为容器生态系统的选择,Containerd 通过提供运行时,可以将 Docker 和 OCI 容器镜像作为新平台或产品的一部分进行管理。

1.4.2、Linkerd


Linkerd是Buoyant公司2016年率先开源的高性能网络代理程序,是业界的第一款Service Mesh产品,甚至可以说Linkerd的诞生标志着Service Mesh时代的开始,其引领后来Service Mesh的快速发展。

其主要用于解决分布式环境中服务之间通信面临的一些问题,比如网络不可靠、不安全、延迟丢包等问题。Linkerd使用Scala语言编写,运行于JVM,底层基于Twitter的Finagle库,并对其做相应的扩展。

最主要的是Linkerd具有快速、轻量级、高性能等特点,每秒以最小的时延及负载处理万级请求,易于水平扩展,经过生产线测试及验证,可运行任何平台的产线级Service Mesh工具。

1.4.3、Envoy

Envoy也是一款高性能的网络代理程序,于2016年10月份由Lyft公司开源,为云原生应用而设计,可作为边界入口,处理外部流量,当然,也作为内部服务间通信代理,实现服务间可靠通信。

Envoy的实现借鉴现有产线级代理及负载均衡器,如Nginx、HAProxy、硬件负载均衡器及云负载均衡器的实践经验,同时基于C++编写及Lyft公司产线实践证明,Envoy性能非常优秀、稳定。

Envoy既可用作独立代理层运行,也可作为Service Mesh架构中数据平面层,因此通常Envoy跟服务运行在一起,将应用的网络功能抽象化,Envoy提供通用网络功能,实现平台及语言无关。

1.4.4、Istio

2017年5月24日,Google, IBM 和 Lyft 共同发布 Istio 的第一个公开版本(0.1)。Istio为一款开源的为微服务提供服务间连接、管理以及安全保障的平台软件,支持运行在Kubernetes、Mesos等容器管理工具,但不限于Kubernetes、Mesos,其底层依赖于Envoy。

Istio提供一种简单的方法实现服务间的负载均衡、服务间认证、监控等功能,而且无需应用层代码调整。其控制平面由Pilot、Citadel 和 Galley组成,数据平面由Envoy实现,通常情况下,数据平面代理Envoy以sidecar模式部署,使得所有服务间的网络通信均由Envoy实现,而Istio的控制平面则负责服务间流量管理、安全通信策略等功能。

1.4.5、Conduit

Conduit于2017年12月发布,作为由Buoyant继Linkerd后赞助的另一个开源项目。Conduit旨在彻底简化用户在Kubernetes使用服务网格的复杂度,提高用户体验,而不是像Linkerd一样针对各种平台进行优化。

1.4.6、国内产品

国内很多团队也已经在着手研究了,这些团队主要分为四类体系:

  • 以蚂蚁金服为首的开源系:蚂蚁金服自研的 SOFA (Scalable Open Financial Architecture)Mesh 在开始的时候走的就是开源路线,他们参考了 Istio 及 Envoy 的设计思想,重新实现了自己的 Service Mesh 系统,旁路网关(Sidecar)基于 Go 语言,该系统的前身是已经开源的 SOFA RPC 框架。蚂蚁金服于 2018 年 7 月正式将其开源,正式的可以用于生产的框架可能还需要一些时间。
  • 以华为为代表的自研系:华为可能在 Service Mesh 概念出来前就已经有类似的想法了,只是没有抽取出一个公共的概念。无论是华为早期的 HSA 还是之后出现的 CSE Mesher,都是对 Service Mesh 的探索。CSE Mesher 的整个架构都是基于华为自身微服务架构经验研发的,其 Sidecar 也是用 Go 语言编写的。如其官方文档所述,其资源占用非常小,常规状态下仅为 30MB。
  • 以腾讯为代表的拿来主义系:腾讯的 Tencent Service Mesh对开源的产品(如 Istio)进行定制,强化吸收后再加入自身特殊的业务逻辑。腾讯选择的Sidecar是Envoy,使用 C++编写,比较符合腾讯的技术栈。其公开的技术并不多,仍然以内部小范围使用为主。
  • 以 UCloud 为代表的适配系:主要也是依赖开源方案,但不是完全将其产品引入,只是对其中几个关键部分添加适配器,以适应企业现有产品,以最小的变更成本引入Service Mesh 体系。

本文由传智教育博学谷 - 狂野架构师教研团队发布
如果本文对您有帮助,欢迎关注和点赞;如果您有任何建议也可留言评论或私信,您的支持是我坚持创作的动力
转载请注明出处!

有关微服务大行其道的今天,Service Mesh是怎样一种存在?的更多相关文章

  1. ruby-on-rails - 如果我将 ruby​​ 版本 2.5.1 与 rails 版本 2.3.18 一起使用会怎样? - 2

    如果我使用ruby​​版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby​​1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更

  2. ruby-on-rails - rspec - 如何检查方法是否存在? - 2

    我的模型有defself.empty_building//stuffend我怎样才能对这个现有的进行rspec?,已经尝试过:describe"empty_building"dosubject{Building.new}it{shouldrespond_to:empty_building}endbutgetting:Failure/Error:it{shouldrespond_to:empty_building}expected#torespondto:empty_building 最佳答案 你有一个类方法self.empty_bu

  3. 怎样用一台手机做自媒体? - 2

    其实做自媒体的成本并不高,入门只需要一部手机即可!在手机上找视频素材、使用手机剪辑视频、最后使用手机发布视频作品获得收益!方法并不难,今天这期内容就来给粉丝们分享一种小方法,每天稳定收益100-300,抓紧点赞收藏!1、找素材(1)使用手机拍摄自己喜欢的经典段落,使用程序把文案内容提取出来(2)也可以在豆瓣、知乎、微博等网站中找一些自己需要的文案素材(3)把文案进行润色修改,可以加入一些自己的观点(4)视频素材可以使用软件中自带的素材,也可以在素材网站中下载完整版的素材2、文案配音(1)把复制好的文案直接导入小程序中(2)调整音色、音调后一键合成音频即可(3)可以选择自己朗读配音,需要花一点时

  4. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  5. ruby-on-rails - ActiveRecord 的 find_or_create* 方法是否存在根本性缺陷? - 2

    有几种方法:first_or_create_by、find_or_create_by等,它们的工作原理是:与数据库对话以尝试找到我们想要的东西如果我们找不到,就自己做保存到数据库显然,并发调用这些方法可能会使两个线程都找不到它们想要的东西,并且在第3步中一个线程会意外失败。似乎更好的解决方案是,创建或查找即:提前在您的数据库中创建合理的唯一性约束。如果你想保存一些东西,就保存它如果有效,那就太好了。如果它因为RecordNotUnique异常而无法工作,它已经存在,太好了,加载它那么在什么情况下我想使用Rails内置的东西而不是我自己的(看起来更可靠)create_or_find?

  6. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  7. ruby - 我怎样才能只写一次 "Text"并同时检查 path_info 是否包含 'A' ? - 2

    -if!request.path_info.include?'A'%{:id=>'A'}"Text"-else"Text"“文本”写了两次。我怎样才能只写一次并同时检查path_info是否包含“A”? 最佳答案 有两种方法可以做到这一点。使用部分,或使用content_forblock:如果“文本”较长,或者是一个重要的子树,您可以将其提取到一个部分。这会使您的代码变干一点。在给出的示例中,这似乎有点矫枉过正。在这种情况下更好的方法是使用content_forblock,如下所示:-if!request.path_info.inc

  8. ruby-on-rails - Rails 单选按钮 - 模型中多列的一种选择 - 2

    我希望用户从一个模型的三个选项中选择一个。即我有一个模型视频,可以被评为正面/负面/未知目前我有三列bool值(pos/neg/unknown)。这是处理这种情况的最佳方式吗?为此,表单应该是什么样的?目前我有类似的东西但显然它允许多项选择,而我试图将它限制为只有一个..怎么办? 最佳答案 如果要使用字符串列,让我们说rating。然后在你的表单中:#...#...它只允许一个选择编辑完全相同但使用radio_button_tag: 关于ruby-on-rails-Rails单选按钮-模

  9. ruby-on-rails - rspec - 我怎样才能让 "pendings"有我的文本而不仅仅是 "No reason given" - 2

    我有这个代码:context"Visitingtheusers#indexpage."dobefore(:each){visitusers_path}subject{page}pending('iii'){shouldhave_no_css('table#users')}pending{shouldhavecontent('Youhavereachedthispageduetoapermissionic错误')}它会导致几个待处理,例如ManagingUsersGivenapractitionerloggedin.Visitingtheusers#indexpage.#Noreason

  10. ruby - 在 Ruby 中是否有一种惯用的方法来操作 2 个数组? - 2

    a=[3,4,7,8,3]b=[5,3,6,8,3]假设数组长度相同,是否有办法使用each或其他一些惯用方法从两个数组的每个元素中获取结果?不使用计数器?例如获取每个元素的乘积:[15,12,42,64,9](0..a.count-1).eachdo|i|太丑了...ruby1.9.3 最佳答案 使用Array.zip怎么样?:>>a=[3,4,7,8,3]=>[3,4,7,8,3]>>b=[5,3,6,8,3]=>[5,3,6,8,3]>>c=[]=>[]>>a.zip(b)do|i,j|c[[3,5],[4,3],[7,6],

随机推荐