SM人人爱:微服务时代的分布式计算

本文作者 蒋彪

苏宁易购高级架构师。2006年至今,历任程序员、技术经理、架构师、高级架构师等职,具有十余年研发及技术管理工作经验。早年在日本参与过みずほ银行(瑞穂实业银行)内部精算系统重构项目,以及东京证券交易所新一代交易系统研发项目,回国后主持过江苏三六五网、麦芽金服等公司的大型高并发互联网架构工作。主要技术领域是微服务设计、容器化部署、容器云计算、DevOps方法论、AIOps模型实战。

比微服务更进一步的,或者称为下一代微服务的,便是服务网格(ServiceMesh)。ServiceMesh是这样一种架构思想——它将传统服务治理框架中的服务发现、注册、熔断、降级、限流这些和业务无关的内容抽离出来,下沉为网络层的系统级实现,让业务代码更加关注于业务逻辑的实现和落地。也正是因为有Service Mesh的思想,诸如FaaS这样的函数式云计算才变成了可能。

为什么使用Service Mesh

目前的微服务架构对于全新的项目或是创业团队而言,实在是“天上掉下来的馅饼”,让小公司也能“站在巨人的肩膀上”。服务发现、服务注册、服务熔断、限流、服务降级、服务追踪、服务监控、分布式一致性、分布式集群,这些在十年前只有大公司才能玩转的东西,现在已经“从天界流向了民间”,小团队也能玩转大技术。

但是并不是所有公司、所有软件项目,都会抱着开放的态度去看待微服务。尤其是对于那些传统企业的软件系统而言,稳定是第一位的,技术革新是次要的。让这样的企业将原有的技术框架改造成微服务架构,无论是使用Spring Cloud还是自主研发的框架,都是无比艰难的事情。

对于这些公司和项目而言,如果能拥有一个对原有软件应用架构及技术架构无侵入性,且基于基础层和网络层快速实现的微服务架构,那肯定是非常有好处的。

所以,ServiceMesh出现了。

而且很有意思的是,Service Mesh的出现和落地与Docker容器化、微服务架构等技术的演化,以及它们背后的厂商,都有很大关系。比如ServiceMesh标准 Istio框架,其背后有三个主要发力厂商:IBM、Google和Lyft,其中Google是Docker容器编排方式Kubernetes的发起者,IBM是全球IT咨询和推广的王者之一。这些厂商都在力推Service Mesh的落地。

Service Mesh的概念在国内也被很多技术专家所推崇,其之所以会成为未来微服务架构的主流方向,是因为它具有以下的优点。

  • 轻松支持多种开发语言,跨语言间的服务调用无须考虑每种语言都要解决的问题。
  • 对业务代码零侵入,开发者无须关心分布式架构带来的复杂性以及引入的技术问题。
  • 为不适合改造的老旧单体应用提供了一种接入分布式环境的方式。
  • 微服务化的进程通常不是一蹴而就的,很多应用采取不断演进的方式,就是将单体应用一部分一部分地进行拆分。而在这个过程中,使用Service Mesh就可以很好地保证未拆分的应用与已经拆分出来的微服务之间的互通和统一治理。
  • 开发出来的应用既是云原生的又具有云独立性,不将业务代码与任何框架、平台或者服务绑定。

至于Service Mesh在国内的落地情况,听闻华为有自主研发的Service Mesh平台,供传统电信BOSS系统接入,一些银行也正在系统内部推进Service Mesh的落地。相信在一两年内,国内会涌现出相当多的落地项目。

早期的分布式计算

自计算机诞生之初,就有了在两台主机上进行服务(进程)调用的需求,早期的分布式主机通信方式如图1所示。

图1 早期的分布式主机通信方式

为了屏蔽跨主机调用的网络通信和其他底层机制,我们在计算机系统中引入了网络栈驱动,将跨主机的通信复杂度交由网络栈处理,使自己可以集中注意力写好代码。

这个模型在早期系统并不复杂的时期尚可维护,但是随着计算机的成本变得越来越低,连接数和数据量也大幅增加。

人们越来越依赖网络系统,就需要找到让机器互相发现的解决方案,通过同一条线路同时处理多个连接,允许机器在非直连的情况下互相通信,通过网络对数据包进行路由、加密等。在这之中,多节点通信时就需要考虑流量控制问题。

流量控制机制可以防止一台服务器发送的数据包超过下游服务器的承受上限。这在分布式环境下是十分必要的。

因为在一个联网系统中,至少会有两台不同的、独立的计算机,它们彼此之间互不了解。计算机A以给定的速率向计算机B发送字节,但不能保证B也可以以足够快的速度连续地处理接收到的字节。例如,B可能正在忙于并行运行其他任务,或者数据包可能是无序到达的,并且B可能被阻塞只为等待本应该第一个到达的数据包。这就意味着,A不仅不知道B的预期性能,而且还可能使B过载,当B不能及时响应的时候,必须对所有传入的数据包进行排队处理。

将应用拆分成业务逻辑层和流量控制层,带网络栈和流量控制的早期分布式主机通信方式如图2所示。

图2 带网络栈和流量控制的早期分布式主机通信

伴随着TCP/IP标准的出现,流量控制和许多其他问题的解决方案被融入了网络协议栈中,这意味着这些流量控制代码仍然存在,但已经从应用程序中转移到了操作系统提供的底层网络层中,这样一来应用就能更加关注业务逻辑本身。将流量控制和网络栈整合在一起之后,早期的分布式主机通信方式如图3所示。

图3 将流量控制和网络栈整合之后的早期分布式主机通信方式

微服务时代的分布式计算

随着时代的发展,当分布式系统的组成从几个大型的中央计算机发展成数以千计的小型服务时,我们就不能再抱有传统的简单冗余备份的想法了,而是要面对新的挑战和开放性问题。

过去用TCP/IP协议栈和通用网络模型可以屏蔽分布式计算中的通信问题,但更复杂、更细碎的分布式架构让我们不仅要考量计算的可用性,更要考量计算的服务发现和过载熔断。这个时候就出现了服务发现和熔断器。

如果基于早期的分布式结构,在应用中加入熔断器和服务发现,我们就能得到如图4所示的加入熔断器和服务发现后的分布式主机通信模型。

服务发现是在满足给定查询条件的情况下自动查找服务实例的过程,例如,一个名为A的服务实例要想找到一个名为B的服务实例,A将调用一些服务发现进程,它们会返回满足条件的B的服务列表。

对于更集中的架构而言,这是一个非常简单的任务,通常可以使用DNS、负载均衡器和一些约定端口号(例如,所有服务将HTTP服务器绑定到8080端口)来实现。

图4 加入熔断器和服务发现后的分布式主机通信模型

而在更分散的环境中,任务会变得越来越复杂,以前可以通过盲目信任DNS来查找依赖关系的服务域名和端口,但是当服务极度分散的时候,每台客户端在不同的网络环境下需要访问部署在不同机房的服务。如果之前只需要一行代码来解析主机名,那么现在可能会需要很多行代码来处理由分布式引入的各种问题。

熔断器是由Michael Nygard在其编写的Release It一书中提出的。

熔断器的基本思想非常简单。将一个受保护的函数调用包含在用于监视故障的熔断器对象中,一旦故障数达到一个阈值,熔断器便会跳闸,并且对熔断器的所有后续调用都将返回错误,完全不接受对受保护函数的调用。通常,如果熔断器发生跳闸,还需要监控报警。

这些技术本身都是非常简单的,它们能为服务之间的交互提供更多的可靠性。然而,与其他技术一样,随着分布式技术的发展,它们也会变得越来越复杂,系统发生错误的概率呈指数级增长,因此即使简单的原理,如“如果熔断器跳闸,则监控报警”,也会变得不那么简单。一个组件中的故障可能会在许多客户端或客户端的客户端上产生连锁反应,从而触发数千个电路同时跳闸,如果处理不慎就会导致系统雪崩。

事实上,Eureka的服务发现和Hystrix的熔断器就是上述技术原理的两个开源实现。

所以,如果我们不是重复造轮子,而是把这些共通的架构整合成公共组件包(Library),并开源提供出来,我们就能得到如图5所示的将熔断器和服务发现整合之后的分布式主机通信模型。

图5 将熔断器和服务发现整合之后的分布式主机通信模型

虽然我们用上述技术实现了微服务,但是随着服务数量呈几何级增长,我们也发现了这种方法中存在着的各种弊端。

第一个弊端在于,这些开源框架对原有代码的侵入性很强,底层替换的成本过高,容易使团队成员将大量的精力花费在底层服务治理机制上,而不能集中注意力关心业务。

第二个弊端是,上面所有的微服务库通常是为特定平台编写的,无论是编程语言还是像JVM这样的运行时环境,如果开发团队使用了微服务库不支持的平台,那么通常需要将代码移植到新的平台,成本很高。特别是对于遗留代码过多的项目而言,大量遗留代码可能是用PHP开发的,用Python开发的,或者用Struts1.0开发的,迁移到新平台的成本巨大。

第三个弊端是,这个模型中有一个值得讨论的问题——管理方面的问题。微服务的底层库可能会对解决微服务架构需求所需的功能进行抽象,但它本身仍然是需要维护的组件,因此必须要确保数千个服务实例所使用的库的版本是相同的或兼容的,否则会非常麻烦。比如,如果大量使用了基于Spring Cloud的微服务,则当Spring Cloud发布了新版本或者修复了重大Bug时,产生的更新和迭代将会令开发者十分痛苦。

所以,如同早期将分布式计算的细节下沉到网络协议中一样,例如熔断器和服务发现这些大规模分布式服务所需的功能,也应该放到底层的平台中。

人们使用高级协议(如HTTP)编写非常复杂的应用程序和服务时,无须考虑TCP是如何控制网络上的数据包的。这就是微服务所需要的,这样可以让那些从事服务开发工作的工程师专注于业务逻辑的开发,从而避免浪费时间去编写服务基础设施代码或管理整个系统的库和框架。

综上所述,将熔断器和服务发现从业务中剥离,我们便得到了对应的分布式主机通信模型,如图6所示。

图6 从业务中剥离熔断器和服务发现后的分布式主机通信模型

将熔断器和服务发现从业务中剥离,让业务回归业务逻辑本身,将底层的任务真正交给底层来完成,这就是Service Mesh的核心思想。

SideCar就是这种思想下的一种具体技术实现,我们在所有主机上运行一个独立的进程SideCar,将熔断器和服务发现以SideCar的形式独立部署,这时的分布式主机通信模型如图7所示。

图7 将熔断器和服务发现以SideCar的形式独立部署后的分布式主机通信模型

随着微服务架构的日益普及,我们也逐渐看到了一系列开源的Service Mesh实现,它们能够灵活地适应不同的基础设施组件和偏好。其中第一个被人们熟知的系统是Linkerd,它由Buoyant创建,灵感源于工程师先前在Twitter微服务平台中积累的工作经验。

在这种模式下,每个服务都配备了一个代理SideCar,由于这些服务只能通过代理SideCar进行通信,因此我们最终会得到如图8所示的网格计算的部署方案。

图8 网格计算的部署方案

由此,我们可以给Service Mesh下一个定义。

Service Mesh是用于处理服务到服务通信的专用基础设施层,它负责通过复杂的服务拓扑来可靠地传递请求。实际上,Service Mesh通常被实现为与应用程序代码一起部署的轻量级网络代理矩阵,并且它不会被应用程序所感知,是非侵入的。

随着微服务部署被迁移到更为复杂的运行时中并使用了如Kubernetes、Mesos这样的编排工具进行自动化运维,我们会将网格计算中的网络管理也集约到Service Mesh控制台上,形成网格计算控制台统一管理下的分布式架构。

本文内容节选自博文视点新书《Docker微服务架构实战》。其中Service Mesh将作为主角隆重亮相。它的横空出世,让微服务落地的路径大大缩短,让现代云原生服务变得近在眼前。然而,技术方案的演进日新月异,脱离完整生态及历史沿革,很难看得懂、理得清、跟得紧、用得上。如果现在有这样一份珍贵图谱,可以让你对微服务架构的认识彻底刷新,一步站在潮流前沿,你还会在阅读原文面前片刻迟疑吗?

  • 内容简介:微服务与Docker是近年来分布式大规模服务架构中两个主流的技术趋势,本书主要介绍中小型企业在架构落地过程中柔性地切入微服务和Docker虚拟化的各种方法。书中主要介绍了微服务架构的各种技术选型、微服务拆分的各项原则、传统应用向微服务架构过渡的方法论、Docker技术原理、Docker跨主机通信选型、Docker与DevOps的整合方法等要点,同时简单介绍了利用Rancher搭建Docker容器云平台的快速解决方案,非常适合云计算从业人员阅读、学习。

原文发布于微信公众号 - 前沿技墅(Edge-Book)

原文发表时间:2018-11-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏花叔的专栏

“公众号数据助手”小程序真的出现了

额,老早之前花叔就想做一个公众号管理相关的小程序,然而微信今天就推出了一个类似的小程序,好了,我不用做了。 回归正题,介绍一下这个小程序吧,通过长按以下二维码能...

47611
来自专栏Android 开发者

[译] 怎样把取消订阅的用户吸引回来

4204
来自专栏程序员互动联盟

单片机距离智能机器人有多远?

提到单片机很多人都很觉得不陌生,大街小巷上面电子产品都用到。近几年随着嵌入式的发展,智能机器人是未来一个大方口,其实智能机器人也是嵌入式的一种,里面融入了生物科...

3695
来自专栏SDNLAB

SDN实战团分享(五):基于VCS技术 + NSX 控制平台实现SDDC网络架构

1.数据中心和新的网络架构需要软硬件一体化 看到前面的兄弟关于NSX架构的分享,感到收获良多,Vmware力争实现的平台是一种和硬件解耦,把大部分问题在虚拟化架...

4026
来自专栏人人都是极客

计算机的基本组成

严格来讲计算机从诞生到现在经历了很多阶段,已经发展成为一种自动地、高速地、精确地进行信息处理的电子设备,也是20世纪的重大发明之一。

1422
来自专栏大数据挖掘DT机器学习

如何入门 Python 爬虫?

刚做完一个跟python爬虫相关的项目,也来说说自己的经验,希望对想学习python爬虫的人有所帮助。 既然问的是如何入门,我想一定是助学者,而且我觉...

3869
来自专栏刘君君

Rest Notes-设计Web架构:问题与领悟

1253
来自专栏腾讯社交用户体验设计

手机QQ里的注册那些事儿

2893
来自专栏我是攻城师

20件程序员必须知道的事

3667
来自专栏java一日一条

源代码的寿命

看看你现在日常工作中的代码。已经运行了多久了?代码有多老了?有六个月?一年?可能都有五年这么久了吧?十年?二十年呢?!这样的代码有多老了?不到10%?还是一半?...

1141

扫码关注云+社区

领取腾讯云代金券