从单体应用到微服务的开发旅程

特别说明

这是一个由simviso团队进行的关于架构演进的云原生分享的翻译文档,这个主要是关于Service Mesh 的分享,分享者是Kong这家公司的CTO。 这家公司有一个著名的开源项目:github.com/Kong/kongjava

让 咱们一块儿来学习下这家CTO是如何从单体应用架构过渡到微服务架构的,Kong又作了哪些事,K8S在其中又作了什么角色,什么是状态机(基于事件架构获得一种设计),在这个过程当中又会遇到哪些坑,哪些经验,尽在视频分享中nginx

视频地址git

【国外前沿技术分享-云原生专题-中文字幕】从单体应用到微服务的开发旅程-上程序员

【国外前沿技术分享-云原生专题-中文字幕】从单体应用到微服务的开发旅程-下github

视频翻译文字版权归 simviso全部:docker

1564657209115

顺带推荐一个专业的程序员后端微信群的圈子:数据库

1564657287116

前言

1564651514614

我叫Marco Palladino,我是Kong的创始人,同时也是这家公司的CTO后端

如他所说,我来自San Francisco California, 今天我想和你们讨论下Service Mesh设计模式

为了打造出适合现代化的架构体系,咱们的架构组织采用了Service Mesh来作过渡api

我想说的是,当咱们的企业变大并经过拆分变成分布式管理以后,那这个企业组织就会变得像多细胞生物同样复杂 (由一个单细胞的形式分裂成多细胞进行协做,总体上看去仍是这一个生命体)

事实上,不管是咱们的团队仍是软件,一旦复杂了,都会去作解耦并进行分布式化管理

能够想象一下,在使用service mesh实现架构现代化的过程当中,它不只仅只是技术采用这么简单

咱们的软件开发方式也由于如下三个方向而发生着改变

其中一种是技术上的更新换代

第二种是组织结构上的过渡

因此架构组织该如何去改变才能去应对新的微服务架构

也就是说,咱们以前对单体架构系统所作的操做模式必须进行改变。即咱们不能以以前的方式去部署,扩展,版本化和文档化这个全新的微服务架构

这三个方向正在改变咱们开发软件的方式

随着docker和kubernetes在2013和2014年的前后发布,一场真正的软件革命也就开始了

Docker和 kubernetes为咱们提供了一种全新的建立应用的方式 随着时间的推动,基于它们,咱们能够以更好的方式来对这些应用进行拓展 不只仅是从技术上带来的好处,更重要的是能够做为咱们业务拓展的首选

事实上除了技术层面,在这场演讲中我会来谈下咱们想要实现的业务目标

若是咱们不能在实现业务目标的同时协调新技术的使用,那么咱们也就没办法在技术转型上走下去

在这个过程当中,咱们必须变得更加务实才行

1564651747122

这是一个从单体架构服务到聚合服务(好比Maven多模块)再到微服务化的过程 Service Mesh就好像一个口袋 口袋里装了一堆的糖果,每一个糖果都是一个微服务,每个微服务多是咱们正常实现的服务,也有多是由函数式实现的服务

同时,API也会改变它们在咱们系统中的角色

咱们一般以API为粒度进行APM(Application performance monitoring)性能监控管理。 自从2007-2008年移动端问世起,咱们须要一种方式去和咱们单体应用进行交互。因而咱们才有了north-south traffic(南北交换,一般指多端与服务器之间的数据交互,也就是说咱们能够经过外部开发者或移动端APP或外部其余形式来访问服务器,重点是外部)

咱们要对咱们的软件进行功能解耦,此时API在咱们的系统中扮演的角色也就愈来愈重要

East-west traffic(东西交换,和上面相比,重点是内部),这个一般是指咱们不一样团队所开发的系统以及不一样系统产品之间所产生的数据交互 接下来,咱们将讨论使用 Service Mesh来对数据层和控制层进行分离,以此来不断的优化扩展咱们的系统

过渡微服务的一些相关要点

1 What does it mean?

1564651936171

但退一步来说,从务实的角度出发,为何要用Service Mesh来进行微服务的过渡

咱们重构单体应用的目的是能够释放团队生产力以及提升业务的可扩展性

此时整个过渡的关键在于团队生产力以及相关业务的可扩展性

1564652026023

在向微服务过渡的过程当中,若是咱们没有作到这二者中的任何一点,那能够这么说,咱们在作的不过是依葫芦画瓢 因此在作这个事以前咱们必须扪心自问,咱们究竟是在为生产而使用,仍是为了用这个技术而用

在这个过程当中,业务应该是首要驱动力,由于咱们写项目的目的就是为了实现业务目标 在肯定业务策略而后采用微服务架构来实现,接下来,咱们要肯定从何时开始,更重要的是到何时结束

2 should we do it?

1564652129555

接下来第二个问题,也是那些想要将项目转向微服务的人想要问的 咱们是否应该这么作,是否应该转向微服务,是否应该放弃如今原有的架构?

1564652181545

从技术趋势而言,咱们不得不问本身,一项技术,咱们是基于实际须要采用,仍是由于这个技术很成熟才去采用

1564652224900

过渡到微服务的过程,这可要比跑单体应用复杂得多。它难就难在一个系统包含了全部的功能,而后咱们将其裂变成一群具备单一功能的系统

目前而言,咱们如今几乎再也不以同一种方式部署或者扩展大型单体应用 但咱们能够经过将一个完整的系统拆分红成百上千个具备不一样功能的单体系统来实现本来的功能

若是说目前微服务没法去解决咱们在管理单体应用上的问题,那么它就会使状况变得更加糟糕

所以技术架构和团队成员必须足够成熟,才能确实的去解决存在的问题

事实上,我真的很推荐在这个过程当中采起步步为营的方式过渡到微服务

基于如下几个理由。首先,经过一步步的去实现阶段性的目标,这能增加团队的信心让他们以为这件事他们能够驾驭 同时,咱们在这个过程当中也能够去适应并随时改变咱们的流程

同时,业务领导者也会随着过渡而变得愈加自信,由于整个过渡是朝着正确的方向进行,随着时间的推移来扩展和让业务变得更加与时俱进

事实上,当咱们来看微服务,来看那些大公司例如Netflix,或者Amazon 它们其实很早以前就已经转型微服务,甚至那时候kubernetes和docker都不存在

究竟是什么在驱动这些公司去作这样的转型?

就拿Netflix而言,为了扩展它的业务规模并再也不拘泥于一个国家和单一的用户体系,它想向全世界迈进,因此它改变了

因此这也是他们的商业目标

对于想要达成的业务需求而言,他们以前的架构并不能知足。所以他们转向了微服务架构以知足业务需求

Amazon一样如此,由于它不仅仅知足于卖一种东西,它更倾向于商品的多元性,所以架构的改变才能知足更为复杂的须要

所以微服务牢牢地围绕着这些业务需求。为了完成咱们的目标 咱们不能各自孤军奋战不管是开发团队或者是管理层。拿Amazon举例,它就是微服务的成功例子

那大家谁知道,是谁决定了让Amazon向微服务去转型?

Amazon CEO Jeff Bezos曾强制推行了六个原则,若是不听从这些原则 那这些人就能够直接被炒了(这段话实际上是讲02年贝佐斯对员工提出必需要遵照的原则性问题)

这种改变很难相信竟然不是开发团队提出的,而是他们的CEO提出的改变

做为企业的领导者经过逐步的改变去完成目标,同时这样能让他们变得更加自信,这才是正确前进的方法

1564652401022

从上面的全部状况来看,为了达到目标,咱们将要经历无数的艰难险阻

咱们能够依据复杂性来决定微服务是大是小

事实上,这些微服务的大小都由业务自己需求所决定,适合就行

3 Let's do it!

1564652440901

但只有当咱们以为微服务是咱们所须要的,同时咱们所选择的路线也是正确的,那么咱们才能继续转型

1564652476421

在转换到微服务的过程当中 ,我定义了两种不一样的策略 其中一种我称之为挖冰淇淋,若是有一大桶冰淇淋,就能够从中一勺勺的挖出大家想要的, 大桶冰淇淋能够挖出各自的服务和业务逻辑,而后就能够在不一样的流程中单独执行和部署

第二种则是乐高法(搭积木),这意味着咱们并不会彻底摆脱本来的单体应用,这种一般适用于比较老旧的项目

但新的功能将会以新的架构进行打造

因此你必须找到一种可以让微服务与过去老的应用从新创建联系的方法,否则这将很难过渡

第三种我称之为nuclear法,这也意味着咱们从头开始打造一切

在转型为微服务架构的过程当中,咱们须要去维护本来的单体应用

从向微服务转型的第一天开始起,咱们就不能从零开始开发,由于它是最差的选择

这须要一支实力强劲的技术团队,同时也须要根据实际状况来肯定技术边界 当你有两个不一样的团队同时工做的时候,一个能够持续交付,另外一个团队则将项目重构并微服务化

当咱们从新构建这个新的代码库时,会将旧代码库的功能重构到新代码库中,这里 问题来了,咱们该在哪里去建立新功能,由于此时咱们的业务依然基于老代码库运行,并无使用新代码库

也就是说,咱们遇到了一个很复杂的状况,难以解决,因此,咱们千万不要抛弃一切,从0开始。接下来就是咱们今天要探讨的冰淇淋策略

1564653126214

举个例子,咱们有一个面向对象的单体服务架构,它具备咱们所须要的全部的功能,这些功能经过不一样对象和类在这个单体服务架构去交互实现

不一样的服务共用了同一个数据库。若是想要扩展这个单体应用,那么咱们只能部署更多这个单体应用的实例 (为了缓解某个扩展服务的压力,其余服务被动进行没必要要的水平扩展,增长了复杂性)

1564653173264

若是这个单体应用是个电商网站,好比咱们常见的amazon.com,那咱们会有不少不一样的服务,好比用户管理,订单管理,库存管理,站内搜索等

这就是一个典型的单体服务架构案例,在这张图里,每一个单独的方块表明了一个不一样的业务逻辑

1564653357795

由于这是一个规模很大的单体服务架构,咱们须要不少团队一块儿去维护它 在这个案例中,有三个不一样的团队在对这个单体应用进行维护,为其建立新功能并将它们投入到生产环境中

1564653409084

如今相信大家如今也知道了单体架构和微服务架构的一些利弊。在单体架构中,会出现一个问题 若是其中一个开发团队对其进行频繁的修改提交,那么就须要在其余团队之间进行大量的协调,以便在生产环境中正确部署这些改变

随着代码库变得愈来愈大,产品开发团队也一样如此。随着时间的推移,问题会变得愈加严重。这会严重影响咱们新版本发布周期的效率

当团队2(有多个团队一块儿开发)也开始频繁的变动代码的时候。遇到的问题更复杂,此时,咱们该如何改变现状?

1564653521163

由于团队2在为搜索服务,库存以及其余模块进行开发工做,若是某个模块须要不少迭代,咱们该怎样将这个模块抽取出来(进行单独开发)

因此咱们所用的冰淇淋策略就是从单体架构中提取出业务逻辑,并将其独立出来

这些服务都很是重要,但它们并非微服务。这就是今天咱们须要作的工做即将它们逐渐改形成微服务

咱们要确保所抽取出来的新服务可以不依赖本来老系统所使用的数据库

咱们的初衷是但愿所抽取的新服务真正的独立

若是老系统对数据库进行了过多的请求

那么数据库将变得不可用

由于咱们不想让服务受到影响,因此咱们想要对服务进行分拆和隔离

而后咱们在生产环境下试运行,接着,当遇到一个或多个部分(这里指图中的方块)也须要进行大量修改的时候,指出并将它们抽取出来

1564653656924

因此咱们如今有三个不一样的服务(如图所示),一个是咱们的老系统,其次是一个稍大的服务,最后是一个小服务

从实际出发,经过一次又一次从单体应用中进行这种服务抽取的操做 或者是从已分离的服务中进一步抽取使之粒度变得更小,以此来解决咱们当下所面临的问题

整个迭代过程不可能一次所有完成,咱们只能以务实的态度去一步一步针对所抽取的业务进行敏捷开发

经过这种按部就班的过程,咱们能够顺带去修改这个项目组织中的其余相关逻辑

以此来给项目的后续迭代提供更多的解耦支持

1564653713155

实际上,在过渡的过程当中,这就是一个重构,相似于咱们之前在单体服务架构内部进行服务的重构。在这咱们有一些事须要去明确

第一件事,咱们须要理解这个模型是什么。若是咱们都不理解这些代码作了什么,那对咱们而言就很难去肯定服务边界

大家知道大部分的单体架构服务的逻辑都过于耦合。正因如此,咱们才须要去明确服务边界并解耦服务 若是咱们都不知道这些,那咱们就根本不可能抽取出来

为了可以重构老系统,咱们也须要去理解如今系统中使用的client,以及若是当错误发生时,会对客户端产生什么样的影响

在微服务转型前,咱们须要知道哪些服务会受到影响

咱们因此作的第三件事就是像其余全部重构同样,须要经过集成测试去验证咱们想要修改的逻辑是否正确 以此来确保咱们的重构不会对本来的系统产生影响

咱们但愿在不影响系统内部运行的状况下,来扩展咱们的系统

咱们不想要中断(影响)必要的服务,至少咱们不能同时去扩展或者改变业务逻辑,这只能一步一步来

1564653819136

当老系统在运行时,有一些事情,可能就是一个小方法的改变,那么咱们就没有必要去将它和以前同样去进行相同的扩展

好比,升级咱们的客户端或者为了将请求正确路由到不一样的服务而去更新路由

客户端会对咱们的单体应用进行请求,但如今那些请求再也不由咱们的单体系统处理而是经过其余服务去处理。因此咱们该如何从新路由这些请求?

1564653866560

在传统业务模型中,咱们会在客户端与服务端之间放置一个负载均衡器(好比nginx)

好比咱们的客户端能够是个移动端程序,当咱们部署单体系统的时候,咱们只需在负载均衡器以后运行此应用的多个实例

1564653911693

但随着咱们系统一步步抽取解耦造成不少微服务,咱们就须要将整个运行架构的某些方面更加智能化才行

首当其冲的一件事就是须要采用一个灵敏的API网关

若是这个网关能作到智能化负载均衡

1564653944308

那么当咱们解耦服务后,咱们就能将API网关做为服务端与客户端之间的代理并实现功能路由。 这就可使得咱们无须升级客户端便可将请求路由到这些新的服务下。这对咱们而言十分重要 若是咱们不这么作,那就必须升级客户端,原有的版本就会出问题,客户体验就不好,也就说会对咱们的业务产生很很差的影响

1564654009311

客户端到服务端之间的代理也就是网关,它必须足够智能化才可以帮助咱们处理咱们架构上的一些操做 像我以前说的向微服务过渡,这并不只仅是技术上的采用例如咱们说的kubernetes,同时也是运营管理上的过渡

咱们不能以部署单体应用的方式来部署微服务架构和SOA架构

咱们须要经过一些策略来下降风险

好比,一个服务的新版本出来了,咱们能够经过使用灰度发布的策略将10%的流量导向新版本的服务

只有当稳定了,咱们才能将流量彻底的导向新版本的服务上同时摆脱掉旧版本服务 与此同时咱们也须要继续保持旧版本的运行,以防咱们须要回滚到前一个版本

1564654321996

在深刻探究微服务和service mesh以前,我想花点时间去阐述下hybrid和multi-cloud

当微服务化的时候,咱们就须要采用像kubernetes这样的平台来运行咱们的服务

由于咱们还有很多服务还在老系统上运行,因此咱们不会在kubernetes中运行全部的服务 咱们仍然会将老系统在咱们以前使用的平台运行,例如虚拟机

当咱们计划向微服务转型的时候,咱们必须制定一个策略来将新老应用平台进行一个有效的链接

咱们没有办法在一晚上之间将全部东西都运行在Kubernetes之上

因此,咱们该怎么作才能将kubernetes上运行的服务和本来的老系统的相关依赖服务从新创建联系

就如我以前所说,这里将整个组织想象成一个复杂的人体组织 那么咱们能够想到,不一样的团队,产品以及业务需求,它们共同的目标都是(所开发的程序单元)要成为彼此独立的存在

从更高层次的角度来看,整个组织不必非要用hybrid ,也不必非要用Multicloud,这须要有一个自上而下的决定

一些公司的项目组织已经运行在不一样的云平台上,之因此采用了hybrid 和 Multicloud 也就意味着随着时间的推移,这些不一样的团队根据项目组织的须要选择了不一样的云平台

从更高层次的角度来看这些公司的整个项目组织,它们为何采用hybrid cloud,这已经不是由于他们想要用,而是他们不得不用

从理想的角度而言,咱们想将全部的服务都放在同一个平台运行

但咱们仍是要面对现实,当下的状况是,咱们须要将多个系统运行在各个地方 因此咱们须要有一个抽象级别更高的架构,在这里咱们须要有工具能够管理这个项目组织下的 Multicloud与hybrid

4 服务粒度

1564654487323

随着咱们从这个单体服务架构中抽取出愈来愈多的微服务

我要给一条建议,结合当下的目标,以合理的方式来肯定微服务边界 我认为是十分重要的。这是我在那些已经十分红功的抽取案例中所获得的经验

就像我以前的例子,咱们不能将微服务化一步到位 咱们能够将一个相对较大的服务抽取出来,而后随着时间的推移一步步解耦它,使之变得愈来愈小

1564654572840

当咱们在看待Service mesh和微服务架构时,理想状况下,这些服务都应该是很小的 而且会以相同的方式互相链接起来。

1564654611113

但现实是,这些服务的大小都取决于咱们以最好的方式来达成的业务目标所产生的规模

咱们不要为了追求微服务而强行使用微服务,有时候咱们须要的多是一个比较大的服务

5 网络

1564654674449

ok,如今咱们经过解耦获得了不少微服务,这些解耦的微服务由不一样的团队独立建立并独立部署 须要强调的是,这些服务不能单独存在,它们须要经过彼此交流才能运行

1564654709861

so,咱们将放弃在单体应用中一些使用方式。咱们基于代码库中的对象(这里的对象是指接口实现类,不是咱们的POJO) 接口和函数调用,经过完美执行这些函数调用,咱们能够调用和访问不一样的对象

可是当咱们将它们解耦成微服务时,这些接口实现类对象变成了服务

接口仍然存在,但全部微服务间的访问将经过网络来进行

举个例子,在一个Java单体应用中,当执行一个函数调用时(调用所定义接口中的方法) 由于底层是基于JVM,咱们彻底无须担忧这个调用,它会被成功处理, java虚拟机将接收调用,并将该调用路由到正确的实现类中

可是在微服务中,咱们将没法作到前面这种

由于咱们将经过网络来进行函数调用,因此咱们将没法保证这种函数请求会在网络中具体哪一个地方进行调用

1564654772073

1564654867392

在咱们的系统中,网络是一个很是不可靠的因素。网络可能会很慢,有延迟也有可能宕机 总之网络和单体应用层面不一样的是它会有各类各样的问题来影响咱们的系统服务

在微服务架构体系中,咱们会有不一样的团队来运行和部署这些服务

团队的思惟方式也须要进行改变

在单体应用中,它有两种状态,工做或者宕机

可是在微服务中,任什么时候候,若是一个服务在运行过程当中出现了问题 此时,咱们应该改变思惟方式,即这里应该有一个服务降级,也就是咱们的架构中应该有服务降级这一部分

由于这些不一样服务中的每个都会出现问题,咱们会建立的越多降级服务,团队能够将它们各自进行独立部署

同时,在组织结构上,咱们的项目团队也要改变相应的思惟模式

在某个时刻,服务一旦发生问题,服务降级系统必须制定该如何进行处理,同时为终端用户提供一个很是好的体验

为终端用户所作的这些全部事情,并非为了咱们本身,咱们这么作是为了给终端用户提供一个更好的产品体验

延迟

1564654964683

接下来说延迟,API 间调用产生的延迟咱们我没法忽略

咱们都知道,网络延时十分重要,对于传统的移动端到单体应用访问来讲

若是移动端App访问咱们的系统时延迟达到数百毫秒,这个对咱们而言 情况并不乐观,咱们能够经过CDN或者缓存来下降延迟,改善网络处理的速度

在微服务中,延时的产生是因为不一样的微服务间的相互的请求愈来愈多,服务A在消费 服务B在消费,服务C也在消费,能够看到,这就会产生服务间相互调用的延时问题

在微服务中传输架构中,一旦一个基础服务发生了服务宕机,调用宕机服务的调用方也会所以而发生新的宕机 在一个单体的服务架构中,一旦一个服务产生异常则和它相关的调用都会发生异常

在微服务中,当产生响应超时,这会影响其余相关微服务,产生链式反应,状况就好像整个系统再也不工做同样

因此延迟是咱们须要去解决的首要问题,这不是咱们过后想fix就fix的 就像安全和性能,这两个不是功能组件,咱们没办法后续添加 咱们只有在编写系统的时候时刻保持这个意识,如何写才能保证性能,如何写才能保证系统安全

1564655036515

安全也成为其中的另外一个组成部分(如图所示),因此如今咱们在网络上拥有的全部这些通讯,咱们但愿可以加密并保护这些交互

例如,经过强制实施双向TLS或者在不一样服务间使用你所知道的方式来加密网络通讯

顺带说一下,这些服务不必非要经过restful api来运行

咱们能够去使用任何一种对咱们所在场景有利的传输协议,大家能够用rest或者gRPC或者其余任何一种传输协议

咱们不受限于任何一种特定的传输方式或者协议,咱们须要知道该如何去透明地保护和加密这些全部的通讯

就像我以前提到的路由,如今咱们有不一样的服务,咱们该怎样在一个系统的某个地方设定路由服务 路由到咱们不一样版本的服务上,将请求路由到那些咱们部署在不一样云主机的微服务

1564655104433

一样若是咱们的服务再也不运行的时候,此时咱们须要进行异常处理 咱们须要可以将请求到这些不工做的实例或者服务的通讯打断。因此在这里咱们须要断路器和health check

在单体服务架构下,咱们没有必要非要设定断路器或者是health check 但当规模达到必定程度例如跑一千个单体应用的时候,它们就变得极为重要 若是从一开始咱们没有这么作,那么咱们在过渡到微服务这条路上就会变得朝不保夕

1564655152175

一样,可观测性也和以前在单体架构服务中不一样 在单体架构中,咱们不须要关心请求会去向哪里(由于很明确), 可是如今在微服务架构中,咱们必须知道

由于咱们须要可以去定位咱们微服务架构中的薄弱环节 因此咱们须要追踪从一个服务到另外一个服务的请求,以及收集性能指标和日志 这样才能便于咱们理解在任什么时候候微服务作了什么,以及若是出现问题的话,定位出错的位置

在没有肯定服务边界的状况下,很难去向微服务过渡 由于在某一点上不可避免地会出现问题,而咱们将没法使用合适的工具来挖掘并找到问题所在

Service Mesh Pattern

1564655209500

让咱们接着讨论Service Mesh

首先,Service Mesh并非一种技术,而是一种设计模式,咱们能够经过各类各样不一样的方式来实现Service Mesh

1564655283873

可是一般,咱们会有一个代理与咱们的服务一块儿运行,经过这些代理能够将不可靠的网络变得可靠

基于此,咱们在构建咱们的服务时就不须要担忧如何处理延迟问题、observability(可观测性)和双向的TLS等等

由于链接点再也不是服务到服务,而是Data Plane(DP,数据平面)到 Data Plane

这些点经过外部网络进行联系,其实就是这些链接点经过Data Plane进行通讯

同时,因为Data Plane能够在服务无感知的状况下执行逻辑,那么咱们能够在此进行异常,延迟以及可观测性处理

在一个Service Mesh中,Data Plane既是代理也是反向代理,这取决于请求的去向

例如,若是这个服务想要调用那个服务,那么这个Data Plane将做为一个代理 由于(这个)服务正进行的请求将经过那个Data Plane进行代理

可是当那个Data Plane收到请求,那个Data Plane将充当一个反向代理,它将接收请求并将其代理到与之关联的服务

咱们须要有一个Data Plane,咱们能够经过不一样的方式来实现Service mesh 每一个底层虚拟机或者每一个你正在运行的服务的副本均可以拥有一个Data Plane

后者被称为Sidecar循环代理,由于咱们将为每个服务器上的服务实例提供一个Data Plane实例

这里会有一个观点,不论咱们每一个副本拥有一个Data Plane,仍是每一个底层虚拟机拥有一个Data Plane都是同样的 这个观点就是,每当有一个服务到服务的通讯,首先会将通讯转到Data Plane,而后由Data Plane接收

这些服务再也不是直接相互通讯,而是必须经过这个不同的系统(Data Plane) 这容许咱们在Data Plane中实现额外的逻辑,也就是说服务无感知是最好的 由于全部双向TLS、全部的可观察性操做都是开箱即用的,团队无须在服务中构建它们

如你所见,这些Data Plane做为联系点,经过这些链接点咱们能够作很任何事 包括将数据库归入这个系统管理中。也是由于当一个服务使用数据库时,咱们仍然想要这个使用过程进行观察 咱们仍但愿拥有Data Plane提供的全部功能,这样一切都将经过Data Plane进行交流

所以,咱们经过分散代理在不一样服务中进行着大量的网络调用

之因此被称为分散式,是由于不像传统的ESB那样,咱们没有将代理实例中心化,而是分散到各个服务中

Kubernetes的定义

1564655428533

so,我刚才提到的Sidecar代理,这会咱们应该知道它是什么了吧。接下来,咱们回到关于Kubernetes的定义上来

Kubernetes将咱们在底层虚拟机上部署Pods的方式进行了抽象

咱们经过使用kubernetes来把咱们的虚拟机群变得看起来就像一台主机来使用

Kubernetes将决定这些Pods的去向

当咱们告诉kubernetes我但愿这个代理是一个sidecar容器

对于这种指定服务容器的其余pods来讲 咱们告诉kubernetes我想要将这个代理部署在这些服务所在的底层虚拟机上(即每个服务所在的pod中都有一个sidecar容器)

咱们但愿Sidecar代理始终部署在底层虚拟机上,由于咱们但愿服务和代理之间的通讯始终在localhost上(适用于每个副本)

假设是由于在localhost中它(通讯)的成功率老是100%

由于咱们没有离开这里(进入到外部网络)而是一直在虚拟机中

在这里和那里之间的网络问题将由Data Plane处理 (译者特别说明:sidecar是用于Kubernetes的,而Data Plane用于service mesh二者所处位置不一样,请注意)

1564655530958

咱们将拥有该代理的一个实例,融合了咱们服务的每一个实例的Sidecar模型

如今,这增长了Data Plane中的问题,Data Plane真的要保持很小的资源利用率,而且在占用上必须很是小

由于咱们将在咱们的系统中为每一个服务的每一个副本都运行一个(代理) 这意味着若是代理自己消耗了许多资源,咱们将耗尽内存资源(例如在底层虚拟机中)

因此若是咱们采用的循环代理越多,咱们就要确保这个代理很是很是小,资源占用很小

顺便说一下,对于咱们本身的服务一样如此,不能占用太多的内存 不然,要么咱们运行在很是大(内存)的虚拟机,要么咱们将很快耗尽内存

所以,在资源利用方面,服务和代理都必须很是的小

这也是为何不能将ESB放在那里的缘由

你能够想象为每一个服务实例运行一个ESB实例,你的服务就甭期望工做了

1564655596263

如今,咱们但愿这些不一样的服务都运行在不一样的Data Plane上,而后咱们须要尽快对这些Data Plane进行配置

当咱们的服务在进行通讯的时候,其实就是这些Data Plane在依赖咱们设定的协议证书进行交流 从总体来看,整个协议很复杂,咱们本身很难去和它们作交流(咱们须要作不少潜在准备,一不当心就容易出问题)

因此,咱们不但愿经过人工的方式来将配置推送到这些不一样的Data Plane上

这里咱们说的就是Control Plane(控制层)了

Data Plane和Control Plane在网络层处理这块儿是很是很是有名的

(例如)你在数据中心运行了一堆Cisco交换机,而且你想要将你的配置推送到这些Casco交换机上

因而咱们想要一个能够容许咱们这样作的Control Plane

把相同的概念应用到软件上来

咱们经过一个Control Plane把配置推到每个Data Plane中

或者是这个Control Plane可让Data Plane从一个统一的地方获取这个配置

但它也能够成为咱们收集指标(运行参数)的一种方式

如今,Data Plane正在一次性收集全部的这些流量(通讯行为) 咱们但愿有一个组件,容许咱们收集日志、收集指标,而且仍然是在Control Plane上

Data Plane位于请求的执行路径上

Control Plane仅用于配置,它仅用于获取这些指标,Control Plane它永远不会在咱们的API请求的执行路径上

1564655673773

基本上,咱们的north-south gateway只是成为了另外一种Data Plane,是另一种代理 它不是咱们的Data Plane,可是容许咱们与底层Data Plane进行通讯

由于它们都是这个Mesh中的一部分,咱们能够在这些不一样的Data Plane间强制实施双向TLS,确保咱们的系统受到保护

即使没有service mesh咱们依然能够作这些事情,那这样的话,咱们就不得不在本身的服务中经过构建来作这些事儿了

从技术上来说,微服务并不必定要必须经过Service mesh来作。但问题在于,若是你想拥有这些优势,就必须本身构建它们

而且在service mesh中也不必定须要Kubernetes,但service mesh的理念可以应用于任何平台

kubernetes 只是让咱们更容易大规模地运行微服务,但没有什么能阻止咱们跨虚拟机来运行service mesh

咱们只须要在服务运行的虚拟机上部署咱们的data plane实例,这样咱们就拥有了一个跑在虚拟机上的service mesh

事实上,咱们更想要的是service mesh可以运行在Kubernetes 中

1564655761962

1564655805094

但就像以前说的,咱们目前依旧有单体应用运行在虚拟机或遗留的平台上

并但愿它经过某种方式可以成为serivce mesh中的一部分 因此咱们但愿数据平台不只仅是在kubernetes 中,还要运行在咱们单体应用的环境中

咱们但愿这种模式(上述的单体应用)也能够成为service mesh的一部分

若是你想让转移到微服务变得更加实际,那么平台无关性无疑是很是重要的

就像以前说的,不一样的服务能够创建在不一样的语言上,这就是微服务的优点之一

由于咱们能够将依赖性很小和功能独立的服务构建在data plane上,这意味着咱们不用重复的去作相同逻辑的事了

在两种不一样的技术编写的两个微服务中,data plane就属于一个对外处理的代理,它和对应的微服务一块儿运行在同一个虚拟机中

基于事件的架构

1564655854020

我再花点时间来谈下基于事件的架构

1564655889611

当咱们讨论 service mesh ,即在讨论微服务时,一般会讨论服务之间的通讯,但这不是实现这些系统的惟一方式

还有另外一种方式是采用基于事件的体系结构来建立它们

这意味着,咱们将在架构中传播一个事件,用更有效的方式来处理诸如捕获状态之类的事情

这里假设有两个不一样的微服务,一个作订单和一个开发票

每次咱们建立订单,再开一张发票,听起来不错

可是,若是一些缘由致使发票微服务变得不可用了,咱们会继续重试直至请求超时

最终发票不会被建立成功,固然最好不要出现这种状况

若是它真的发生了,那么系统中状态的传播就会被中断,过后须要花很大的代价去修复

所以对于上述案例用状态进行传播的方式,咱们能够考虑使用事件

例如让发票的微服务就绪以后再去处理订单建立事件,这样咱们的状态就不会丢失了

这种方式的风险在于,咱们能够用例如kafka之类的当作事件收集器,但系统中的其余服务可能真的会发生一些异常状况

因此但愿在这些服务前面有一个data plane,由于咱们想要确保服务事件可以到达事件收集器(kafka)

1564655982636

因此咱们能够采用Kafka或某种日志收集器来处理咱们的一些用例,固然必须确保日志收集器可用,不会发生故障

一般咱们更容易将精力用于保证一项服务的正常运行(例如日志收集),而不是将它放在给每一个服务传播状态信息上

由于咱们只有一个组件的话只须要确保它能正确持续运行,相反,若是组件不少,那么全部的组件都必须处于正常运行 咱们能够集中精力让运行变得更加可靠一点,使得状态的传播也变得更加可靠

1564656020982

就像我所说的企业组织架构正在转变,而咱们的系统也逐渐往一个复杂的生命体方向靠拢,所以我很喜欢用神经系统来作比喻

咱们的身体由大脑中的CNS(中枢神经系统)和PNS(周围神经系统)两个不一样组成部分组成

周围神经系统将咱们身体可以理解的全部信息存起来,而后将它们传递给CNS(中枢神经系统),以便CNS(中枢神经系统)能够处理它们

1564656059189

这与 control plane 和 data plane 的概念很是类似

data plane将位于咱们每一个服务,每一个单体应用的外围,以及每一个函数式(例如lambdas)的外围

可是相关配置,监控以及可观察性,都将由control plane处理

Kong作了什么

1564656095861

我以前说过 我是Kong的联合创始人兼CTO, Kong提供了一个有效地开源 control plane和data plane,能够容许在组织中进行不一样架构的管理

在全球范围内运行着超过一百万的Kong实例来帮助开发者进行data plane管理 咱们给那些须要进行架构转变的团队提供了技术支持以帮助他们从单体架构到微服务到 Service Mesh 到Serverless的过渡

1564656133017

过渡到微服务是一个很复杂的课题,由于它影响了三个不一样的方面

但更重要的是咱们必须将这个过程和咱们要达成的业务目标相结合,否则就像我说的,它只是依葫芦画瓢,为了使用微服务而微服务

首先是业务转型

咱们必须实事求是,若是没有必要,咱们不须要立马转型微服务或者当即拥有数千个微服务

主要在于咱们老是有时间来将服务变得愈来愈小

所以,没必要那么着急,先将服务提取到中等大小,而后随着时间的推移使其变得更小

事实上,我想说只有当服务须要变得更小的时候,那么咱们才能将它变得更小。这才是最好的过渡方式

由于它既能够提升咱们的生产力,也加强了咱们的业务

经过采起使用技术的方式,使咱们可以向这些新架构微服务过渡

但也可经过一个很是务实的方式链接如今正在提供业务服务的老应用程序(程序待重构)

那些仍然是最关键的组件,将它们与咱们新的greenfield (新开发的)微服物架构链接起来,这将成咱们系统的将来

因此这须要在新旧之间创建联系

感谢你们的倾听

1564656218456

提问

因此大家还有其余问题吗?

提问部分:就好比说又一个单体应用,按照演讲者以前讲的意思将服务逐步解耦使之变得愈来愈小 Amazon就表示对他们来讲这样作就会代价很大,因而他们就中途放弃 直接从新开始,直接开始全面微服务(抛弃原有的系统),对此你有什么见解

就像我说的,这其实也是一种选择。只要企业/开发团队已经准备好能作全面微服务化的准备 同时也有着清晰的思路,那么这种过渡到微服务的方案也是可取的

在采用那个方案的时候,咱们必须分析利弊。固然,Amazon经过分析他们的利弊 若是选择从新打造而不是从单体应用慢慢过渡到微服务,这种状况下,利远大于弊

在我看来,它仍然是一个不多有公司可以成功过渡到微服务的策略

固然这些事情咱们也须要归入考虑

提问部分大体意思:微服务间存在着大量的调用 然而咱们经过Data Plane进行网络通讯的延迟远高于服务与服务之间的本地调用,有没有什么下降延迟的办法?

系统能够为咱们提供指标,用以了解延迟瓶颈的正确位置 因此若是咱们须要经过网络,咱们将获得比经过本地函数调用更多的延迟,这是可行的

实际上,若是代理没有正确创建,这个网络处理就会增长更多的延迟

由于你知道的双向TLS 以及可观测性操做都会在咱们的处理过程当中增长延迟

因此咱们能够作的就是在Data Plane层缓存一些信息,这样请求可能就不须要进入到外部网络中,因此我想到的是 在这些不一样的服务间组织实现某种意义上的全局缓存,假设这的方式是可行的,由于对于某些用例(场景)咱们是没法实现(缓存)的

而对于其余人而言,他们彻底接受了最终一致架构的概念,延迟只是它的一部分

而且客户端就是这样创建起来的,他们考虑到了这一点,因此一切最终都是一致的,会有一点延迟 咱们将在客户端看到信息,它不必定是最新的,但它最终会保持一致

在考虑延迟问题的时候,Service mesh可以经过一系列方法来帮助咱们定位延迟问题,这不只仅只是网络延迟,一样也多是服务延迟

咱们为了可以肯定是否必须对那些已经对其余服务产生性能瓶颈的服务进行升级,因此须要一种观察的机制 这样在实际使用中,这也能让咱们实现一些缓存方法去提升咱们架构的性能

固然,由于咱们是基于网络去请求,因此咱们应该从实际出发 去分辨哪些延迟是正常的,哪些是不正常的。若是不正常 那么咱们就必须确保系统的最终一致性,并以此为前提,咱们来构建咱们的客户端

相关文章
相关标签/搜索