InfoQ 研究中心诚意出品,一份报告带你走进中国 2000 万开发者 了解详情
写点什么

关于 Cloud Native 架构与 Matt Stine 的一次对话

  • 2015-06-30
  • 本文字数:7508 字

    阅读完需:约 25 分钟

在于马萨诸塞州的波士顿举办的 O’Reilly 架构大会上,Rags Srinivas 对 Matt Stine 进行了一次采访。Matt 在采访中谈论了 Cloud Native 架构以及它在文化和技术方面的某些挑战,他也提到了 NetFlix 的某些服务,以及如何通过 Spring 对其进行封装,在这个平台上进行微服务的架构设计与开发。他还谈到了 SOA,以及其中可能缺失的一些概念。

InfoQ**:你们好,欢迎来到这里。在我身边的是来自 Pivotal的 Matt Stine,我们现在正处于在马萨诸塞州的波士顿举办的 O’Reilly软件架构大会的现场。那么 Matt,如果你能够为 InfoQ**的读者们介绍一下你自己的话,那就再好不过了。

Matt:当然了。是的,正如你所说,我是 Matt Stine。我来自于 Pivotal,自从几年之前 Pivotal 成立以来,我就以某种形式参与了 Cloud Foundry 团队的工作。我的工作职责很多:工程师、技术传道士、还要管理一些技术市场工作以及撰写博客。最近,我要负责一些为 Cloud Foundry 开发的一系列服务的产品管理工作,包括 Spring Cloud 和 Netflix OSS。

InfoQ:我知道你最近编写的一本书刚刚由 O**’Reilly出版,并且在这次大会中发放给与会者,内容是有关于 cloud native架构的。从架构师或开发者的观点来看,cloud native**这种架构到底有什么意义,能举几个例子吗?

Matt:我所称之为“cloud native”的这个概念是多种不同思想的一个集合,这些思想与许多公司正在转移到云平台的趋势是一致的。这些思想包括 DevOps、持续交付、微服务、敏捷基础设施、康威定律,以及根据商业能力对公司进行重组。这里面包括了许多东西,cloud native 是一种我与其他一些人约定俗成的名称。如果说这本书能够为读者带来什么,可以说我在书中所说的主体是关于人、组织结构以及文化的变革的。其中也稍微提到了一些技术方面的内容。

虽然本书的主题是 cloud native 架构,但书中的内容都是与人有关的话题,这看上去有些奇怪。但事实上,为了让这种架构发挥其作用,必须对你的公司进行变革,以促进它的功效。一旦你实现了公司的重组,这个架构就会为你带来很大的利益。因此重点在于这一趋势并不仅仅是一种技术趋势,甚至可以说它的重点并不在技术上面,而更多的是一种文化与组织结构变革的趋势。

InfoQ:好的,你的回答为接下来的问题进行了很好的铺垫。微服务从本质上来说是一种全新的概念吗?还是说它其实就是 SOA,只是旧瓶装新酒而已?

Matt:我曾经也参与过关于微服务与 SOA 之间的关联的这种讨论。在某种程度上,我觉得这种讨论的意义不大。这么说吧,如果我们比较一下 SOA 在维基百科介绍中的前几个段落,那么在我们如今称之为微服务的概念中确实有许多方面与 SOA 是非常相近的。我认为真正的区别在于供应商是如何实现 SOA 的,他们所专注的是将所有东西都扔到一个新的中间件中,称其为企业服务总线(Enterprise Service Bus - ESB),让它来取代所有其它所有大型的中间件,因为那些中间件听起来不够酷,已经无法成为服务的卖点了。我不是说 ESB 是一种糟糕的技术,而是说我们使用的方式不对,只是用一个新的一体性架构去取代现有的一体性架构,这种方式只是把复杂性从一端转移到另一端而已。要想转变为一种更加面向服务的架构,以上这些做法都是不必要的。

看一看服务的基本原则,一个清晰的专注点,一个清晰的契约以及一个清晰的 API。换句话说,SOA 背后的原则在本质上与微服务背后的技术原则在概念上是趋向于一致的。而在 SOA 这个趋势中,你所忽视的东西是对文化、组织、甚至运维方面的问题的强调。

我一直在考虑运维的问题,而当我听到 Neal Ford 关于微服务的演讲时,这一想法终于清晰地展现在我眼前。他在演讲中表示:当他看到在架构图中包含了 ESB 时,这些架构图看起来很不错,也容易理解,但从运维的角度来看,它们实际上什么都没做。

然后我们继续前进,在这个基础上实施持续交付。这期间我们遭遇了无数的意外情况,因为没人考虑过这种架构运行在生产环境时会发生什么情况。之后我们将目光投向了微服务,它是在 DevOps 与持续交付这些概念出现后第一批浮现出的架构选择之一。现在我们有了一个个团队,在他们的工作内容的背后是这些概念在支撑着他们的思想,然后这种特殊类型的架构就突然间出现了。对于这些新型架构,我们现在只是为它们打上了一个“微服务”的标签。

因此我认为,从原则上来说,这两者这间没有太大的差别,但从实现的角度来说,这两者之间存存在着巨大的差异。我想这也是关于微服务与 SOA 之间的异同点的讨论会出现的原因之一。从 SOA 和微服务的基本原则以及背后的历史来考虑,它们没有多大的差别。但在实现微服务与 SOA 的过程中,从参与者每天的工作内容来看,这两者是完全不同的。

InfoQ**:在 SOA方面,一个经典的失败案例是一体性的 UDDI。不知道你是否还记得它,也就是统一描述、发现和集成?即使从微服务的角度来看,服务发现也仍然是十分关键的,是吗?**

Matt:没错。

InfoQ:那么在微服务的世界,它的重要性到底怎样,具体又发生了些什么?

Matt:是的,感谢你事先已经将问题发给我看过了,我也因此重新看了一遍 UDDI,让我想起它代表什么含义了。在它流行的年代中,我其实从来没有使用过它。当然,我也不清楚它到底算不算是流行过,但至少当时人们确实在谈论它。我想我们如今所说的服务发现和当时已经有了很大的不同。就我对 UDDI 的理解来看,它很像一本电话簿,我作为某个服务的开发者打开了这本电话簿,以寻找我所需的某些东西,例如某个处理信用卡的服务。

我首先会提出的第一个问题是:“那么,这里面有哪些可用的信用卡处理服务呢?”根据 UDDI 的回答,我会选择一种服务。在选择了该服务之后,我会进行查看该服务的契约定义,也就是某些 WSDL 文档。随后我就选择了这种 WSDL,很可能会根据这个 WSDL 生成一些代码,通过它与这个信用卡处理服务进行交互。

最终你可能会产生某种幻觉,即通过目录提供的这些服务是一种松耦合的架构方式,但实际上你又与那个 WSDL 中所定义的特定契约产生了紧耦合。一旦 WSDL 产生了变化,你所生成的代码在一瞬间将失去作用,你将不断地在这个循环中无法自拨。

因此,我认为对如今的服务发现来看,它仍然具有目录这一思想,但它的目的不是告诉让我们查看“其中有”哪些服务。而是表现为我们知道需要某些服务,并且知道在架构中存在着这种服务,而且这种服务有一个逻辑名称。我只需要知道如何将这个逻辑名称转换为实际的网络地址,并通过该地址与服务进行通信。

因此在这个情况下我所编写的典型代码是这样的:我在创建一个存储服务和一个客户服务,并且我知道该客户服务需要调用这个存储服务,只是还不知道这个存储服务的实际地址。我不想对这个地址进行硬编码,因为这会造成对这些服务的紧耦合。通过使用一种服务注册表,我就可以对从哪里获取这个组件的信息解耦。通过这种设计,我就能够随意地对这个存储服务进行各种操作:可以对它进行横向扩展、或者紧缩,也可以把它转移到其它地方(因为我有时希望使用云架构)。即使如此,也不会破坏运行中的客户服务。

此外,我们也将对该服务契约的发现与服务注册表本身进行了完全解耦。你可以看看 Netflix 的 Eureka,在其中你找不到任何 WSDL 或规格说明,以告诉你它使用的 API 是什么样的。你只是获得某个服务的地址并进行连接,它会告诉你“我的 API 在这里”,或者你也可以通过其它某些方法获得它的 API 信息。但发现过程与 API 是两种相互独立的关注点,并且已经被我们拆分了。而在 UDDI 中,这两者之间具有更强的耦合性。

再重申一下,如果从很高的层次来思考,就像思考 SOA 与微服务的区别一样,那么在服务发现与 UDDI 之间确实存在着某些类似之处,但它们的实现方式是完全不同的。

InfoQ**:我想你刚刚提到了 Netflix的一些微服务,我知道你目前参与了 Spring Cloud的工作,对吧?那么能否请你大体上谈一谈 Netflix OSS与 Spring Cloud之间的共同效应,以及一些你所特别关注的组件?**

Matt:Pivotal 与 Netflix 之间的关系越来越接近,并且还在不断发展,尤其是在 Sprint 团队与 Netflix 之间,但 Pivotal 的其他服务也在增进与 Netflix 的关系。Netflix 长期以来一直都在使用 Spring 技术,他们已经成为了 Spring Boot 的一个重要的支持者和用户,在 Netflix 中有大量的应用都是使用 Spring Boot 编写的。在 Spring Boot 诞生之前,他们也是 Grails 的重度用户。

在创建 Spring Cloud 时,Spring 与 Netflix 的工程团队之间进行了多次交流,以更好地了解服务的工作方式以及如何正确地使用它们。我们所做的不是随便找一种开源实现,对其进行一下简单封装就丢给他们那么简单。为了确保出色地完成这个产品,我们之间进行了大量的合作。我们还将继续进行更深入的交流,包括 Spring 的下一代产品和 Netflix 在云技术方面的下一代产品将如何实现,并让它们联系更紧密。因此,我期待着在今后的几个月和几年中,这两个团队的相互交流能够带来更令人激动的产品。

InfoQ:好的。从一个开发者的角度来看,要做的事情确实很多。我的意思是,开发者要使用服务发现,当然还有很多常见的任务 —— 要扩展至大规模,要连接日志记录等等,对吗?

Matt:没错。

InfoQ**:显然,像 Cloud Foundry这样的 PaaS能够帮助开发者,对吗?能够请你再详细地阐述一下,微服务方式与 PaaS方式,或至少说 Cloud Foundry方式有哪些相似之处,或者说它们并不相似?**

Matt:回想 9 个月以前,当时我们还完全没有考虑到这些问题。当时才刚刚有了微服务的思想,还处于发展的初期。当时还有一些关于 Cloud Foundry 的讨论:从开发者的生产力、运维上的效率以及提高质量来看,它意味着什么?当时我们的想法是通过它将那些遗留代码搬迁到云端。这里面有很多问题,实现这一目标非常困难,甚至是不可能的,因此在大多数情况下你是不会这么做的。

然后这些问题就来了:“好吧,那么为在 Cloud Foundry 上运行而开发的应用程序看起来是怎样的呢?”然后我开始认真思考这个问题,你怎样回答呢?当时,我们的答案是十二要素(Twelve Factor),这是由 Heroku 所提出的宣言。我们开始在 Cloud Foundry 中使用了其中提到的 buildpack 模型,十二要素非常适合于 Cloud Foundry,你甚至可以说 Cloud Foundry 是专用于运行十二要素应用的平台。但即使你或许能从中得到某些如何让应用正确运行的实现细节,但如果你说“我打算设计一种能够正确运行的应用”,然后我们表示你可以创建一个大规模的十二因素应用。这真是我们的目标吗?应该不是。

因此我开始把目光转向微服务。在 Cloud Foundry 与微服务之间存在着一种协同性,甚至是共生性。使用微服务时,你必须处理许多运维方面的挑战。事实证明,Cloud Foundry 所要应对的运维挑战也是完全一样的。回头看看 Cloud Foundry:有一些应用在上面运行得挺好,有一些则不然。再看看微服务通常是怎样创建的,从 Cloud Foundry 的角度来看,它们的创建方式几乎是一致的。

这两者之间并没有依赖关系,但如果能够将它们连结在一起,将会产生一种强大的协同作用。为此,我发起了这次讨论。在上一次 Cloud Foundry Summit 大会上,我提出了一个演讲主题:“Cloud Foundry 与微服务:一种共生关系。”这个提议得到了批准,并由我负责演讲。在之后的几个月之内,这个观念得到了人们的接受和应用,最终使我们完全投入到这个讨论中。

同时,Spring Cloud 项目的开展与这一讨论并没有什么关系,而最终我们让这两个小组坐到了一起。我们现在可以全力打造 Cloud Foundry、微服务、Spring Cloud 和 Netflix。我们的目标是创建一种 cloud native 应用平台和开发框架,创建一种全栈的解决方案,用于打造架构、管理(至少从技术角度来看)你需要处理的一切。余下的东西就是我们无法通过技术解决的问题:文化与组织结构方面的挑战。

InfoQ**:如今整个产业都在为容器技术疯狂,是吗?你能否描述一下 Spring Boot的特征?我会将 Spring视为一种轻量级容器,但我不确定 Spring Boot**是否是一种轻量级容器。另外,你对于容器的一般性看法是怎样的?

Matt:当我们在谈论容器的时候,我们其实经常是在谈论 Linux 容器,我假设你所说的容器是指 Java 容器。不幸的是,容器这个术语承载了太多内容。不管怎样,大家都在谈论 Docker。那么 Docker 和 Spring Boot 之间有什么关系呢?

创建一种符合 Boot 应用规范的 Spring 应用非常简单。Boot 帮我封装了用于运行 web 应用的 servlet 容器,我可以在 Tomcat、Jetty 或 Undertow 之间进行任意选择。

现在我有了一个自包含的 JAR 文件,它能够完成我所需的一切功能。我能够轻易地将该文件加载到某个安装了 Java 的 Docker 容器镜像文件中,然后创建一个新的层,以加载 Spring Boot 应用。现在我有了一个可移植的容器镜像,其中包含了可进行发布的 Spring Boot 应用。这是一种非常良好的协作效应。很快你就能够通过 Cloud Foundry 或 Lattice 在 Diego 上运行 Docker 或 Rocket(或其它什么)镜像了,这套方案为你提供了非常强大的工具。

从持续交付的角度来看,我在笔记本电脑上所运行的应用,通过持续集成管道所发布的应用,以及在 Cloud Foundry 上的生产环境上所运行的应用是完全一致的,这是一种非常理想的场景。持续交付的一个核心原则是差异的决定性,哪怕一个很小的差异也可能会造成在某个环境下运行良好的应用,换了一个环境就无法运行了。因为我清楚地知道,我所开发的、测试的、以及在生产环境中运行的应用在文件系统级别上是完全相同的,因此我对应用能够正常运行很有信心。

关键的不同点显然在于不同的环境中运行着不同的核心,它们应当是完全相同,或是非常接近的。但这一点应当是唯一的不同之处了,在几年之前,我们还无法轻易地实现这一点,甚至要接近实现这一点也是非常困难的。我们可以通过虚拟机来模拟这一点,但它们的价格相对高昂,并且启动与调整时间也很长。而如今在容器中只需几秒钟就可以完成这一切。

不过现在你还有许多问题需要处理。你如何进行水平扩展?你如何管理这些镜像的创建与更新?如果你不能很好地管理容器镜像的维护,让它们继承于某个通用的根镜像(这种做法比较合理),那么你就会创建出大量的镜像,而它们之间无法共享内容。你会很快地填满整个硬盘,并且产生效率低下的问题。这些技术看上去很简单,但别被这种简单性所迷惑了。我可以在五分钟之内就创建好一个容器镜像并让它运行起来,这只不过是一个开始练习而已。随着你逐渐地增加规模,有许多工作需要靠整个团队的纪律流程进行规范,并且需要通过一系列工具负责创建与管理这些镜像文件,让它们保持一致性与可重复性。因此如果有多个团队在开发应用,这些团队不需要各自定制一套根文件系统,我们也可以从容器镜像带给我们的效率中受益。

我想说的是,天下没有免费的午餐。这些工具都十分强大,但都不是可以轻易掌握的。为了有效地利用它们,你不仅要学习它们的使用,同时也要改变你的某些工作方式。

InfoQ:InfoQ的读者们有许多实践者和架构师,他们在敏捷方面有着大量的实践经验。我们从敏捷开始,那么这是我们今天最后一个问题了。从架构的角度来看,敏捷是否有意义?有时人们的说法是持续改进以及实施敏捷,对吧?那么架构与敏捷如何相互融合呢?

Matt:我有一种感觉:由于在敏捷方法中存在着一些仪式,而这些仪式有时会掩盖了敏捷的核心思想,就是迭代式地对反馈进行回应。我们不需要过度的计划,不需要过度的设计,也不需要过度的架构。我们已经看到了这一点,但如果我们稍不留意,就会从光谱的一边跑到相反的另一边。在这一边的做法是繁重的前期计划与设计,或者说瀑布模型或其它任何名称。而另一边的做法是完全不考虑任何东西、不进行任何设计、不进行任何头脑风暴,只是沿着车轮前进,不断踩下油门,前进、前进、前进,编码、编码、编码,测试、测试、测试……我们天真地相信这种方式最终会带来良好的结果。这两种极端都不是正确的方式。

几年之前,Rich Hickey 的一次讲座激怒了许多人(可以在 Info 上找到这个链接: http://www.infoq.com/presentations/Simple-Made-Easy)。在演讲中的某个部分,他将测试驱动开发比喻为“护栏驱动开发”。他说:“我在开车时不会不停地撞击马路两边的护栏,并期望这些护栏能够让我保持在正道上。”很多人因此觉得他表示的意思是测试驱动开发是一种糟糕的或愚蠢的实践,“你不应当这么做,你不该采用 TDD” 。我在这里不是要为 Rich 开脱,但我不认为这是他的真实想法。我想他要表示的是你仍然有可以思考的余地。实际上,思考确实是至关重要的。思考如何架构、思考如何设计、思考你的前进方向,然后将 TDD 等实践作为一种工具以帮助你达到目的地。

因此我们可以停下编写测试与代码的工作,想一想我们的前进方向是什么?这个模块与 API 看起来应该是怎样的?我们所需要处理的关注点是什么,到底是难以为它编写测试,还是说我们根本不知道要为什么编写测试?所以我们或许应当退一步,找一个房间,挂起一块白板,把一切设计都画在上面。但我们不是要将这些图形转变为重量级的正规 UML 文档,进行轻量级的架构与设计是完全有可能的,但首先你要意识到,在开始动手敲键盘之前,工作应当已经在你的头脑中进行了。

我想,如果你在这条光谱中为你的团队找到了适当的位置,那么你也将找到成功之路。而这个位置很大程度上取决于你所试图创建的功能。它的内在复杂性是什么?如果你只是要创建一个相对较小的应用,那么你或许不需要进行那么多架构工作。但要创建某种由微服务组成的大型分布式系统,以“web 规模”运行,并打算支持几百万用户。好吧,那么只是使用 TDD 应该是不行的。

因此,就像软件工程中的所有问题一样,对这个问题也不存在一种二元的回答,它不是非此即彼的。在这两个极端之间必定存在着某个适合你团队的正确答案,你必须把问题放到你所试图解决的问题上下文中以找到答案,也就是你需要多少架构实践、以及多少文档工作才能最终实现你的目标。如果你能够退一步,将敏捷当作某种保持反馈循环运作的手段,即获取反馈、对它进行回应、进行方向修正、并打造正确的产品,那么剩余的部分会自动朝着正确的方向前进。

只要将持续改进、持续反馈以及持续对反馈进行回应作为工作中的核心思想,那你就可以随意选择如何进行架构设计,也可以选择结对编程和 TDD。你可以随意选择任何实践,并且发现适合你现状的平衡点是什么。

关于受访者

Matt Stine**** 是Pivotal 的一位技术产品经理。他是一位具有 15 年企业级 IT 产业经验的老手,项目经验涵盖了多种业务领域。他也是 O’Reilly 最近出版的 _《Migrating to Cloud-Native Application Architectures》 _ 一书的作者,可以免费下载这本电子书。

查看英文原文: Cloud Native Architectures - a Conversation with Matt Stine

2015-06-30 00:185256
用户头像

发布了 428 篇内容, 共 162.4 次阅读, 收获喜欢 33 次。

关注

评论

发布
暂无评论
发现更多内容

xxl-job 源码运行解析,java基础编程视频

Java 程序员 后端

ZooKeeper实现生产-消费者队列,万字长文总结Java多进程

Java 程序员 后端

“一学就会”微服务的架构模式,一名毕业三年的女程序媛面试头条经验

Java 程序员 后端

Vue 生命周期 钩子函数,mybatisdao接口工作原理

Java 程序员 后端

windows下nginx的安装及使用,linux实用教程第三版pdf

Java 程序员 后端

Tomcat性能优化前后,有多大的差距,今天测试给大家看,linux视频教程推荐

Java 程序员 后端

Vue 数组操作,java基础教程百度网盘

Java 程序员 后端

yum安装ansible报错如何解决,自定义线程池面试题

Java 程序员 后端

“ShardingCore”是如何针对分表下的分页进行优化的,深入理解linux内核架构

Java 程序员 后端

Tomcat实现热部署、热加载原理解析,线程池底层实现原理

Java 程序员 后端

Tomcat性能优化前后,有多大的差距,今天测试给大家看(1)

Java 程序员 后端

Zookeeper 集群部署的那些事儿,消息队列rabbitmq面试

Java 程序员 后端

Zookeeper用作注册中心的原理,张孝祥jsp视频教程

Java 程序员 后端

Vue 数组操作(1),java设计模式书籍推荐有代码讲解

Java 程序员 后端

【终极预告】Apache ShardingSphere Dev Meetup 彩蛋篇

SphereEx

开源社区 ShardingSphere Meetup SphereEx 热门活动

“打工人”都在用的邮件使用规范,入职3个月的Java程序员面临转正

Java 程序员 后端

vue遇到的坑,linux网络编程pdf百度云

Java 程序员 后端

zookeeper原理篇-Zookeeper选举过程分析,深入linux内核架构pdf下载

Java 程序员 后端

“情商比智商重要”,java面试代码题

Java 程序员 后端

ICCV 2021人脸鉴伪比赛全赛道冠军!AI反诈这块,百度算是弄明白了

科技热闻

requests库与 lxml 库常用操作整理+总结,爬虫120例阶段整理篇

梦想橡皮擦

11月日更

zabbix监控nginx、mysql、java应用,64位java8百度云盘

Java 程序员 后端

vue移动端自适应,mybatis面试问题

Java 程序员 后端

Flink 的容错管理详细剖析

yuanmore

flink 11月日更

Vue学习之自定义指令,宅家36天咸鱼翻身入职腾讯

Java 程序员 后端

技术分享| RTC通讯中常用的音频格式

anyRTC开发者

音视频 WebRTC RTC 语音通话 音频格式

WPF学习——依赖项属性,中软国际java面试流程

Java 程序员 后端

zookeeper分布式锁,java开发技术教程

Java 程序员 后端

XXL-Job启动源码详解,Java日常开发的12个坑,你踩过几个

Java 程序员 后端

Vue学习之v-if和v-for指令,tomcat常见面试题

Java 程序员 后端

Vue学习之事件修饰符,java后端开发入门

Java 程序员 后端

关于Cloud Native架构与Matt Stine的一次对话_语言 & 开发_Rags Srinivas_InfoQ精选文章