Springboot与微服务翻译

在过去几年中,“微服务架构”这一术语如雨后春笋般涌现出来,它描述了一种将软件应用程序设计为一组可独立部署的服务的特定方式。虽然这种架构风格没有明确的定义,但在组织、业务能力上有一些共同的特征:自动化部署,端点智能化,语言和数据的去中心化控制。

“微服务” – 软件架构拥挤大街上的有一个新术语。虽然我们自然的倾向是轻蔑的一瞥将它一带而过,然而我们发现这一术语描述了一种越来越吸引人的软件系统风格。我们已看到,在过去的几年中有许多项目使用了这种风格,并且到目前为止结果都还不错,以致于这已变成了我们同事在构建企业级应用程序时默认使用的架构风格。然而,遗憾的是并没有太多的信息来概述什么是微服务风格以及怎样用这种风格。

简单来说,微服务架构风格[1]是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并且可通过全自动部署机制独立部署。这些服务共用一个最小型的集中式的管理,服务可用不同的语言开发,使用不同的数据存储技术。

与单体风格作对比有助于开始解释微服务风格:单体应用程序被构建为单一单元。企业级应用程序通常由三部分组成:客户端侧用户接口(由运行于开发机上的浏览器里的HTML页面和Javascript组成),数据库(由插入到通用关系型数据库管理系统中的许多数据表格组成),服务端应用程序。服务端应用程序处理HTTP请求,执行领域逻辑,从数据库中检索、更新数据,选择、填充将要发送到浏览器的HTTP视图。服务端应用程序是一个单一的逻辑可执行单体[2]。系统的任何改变都将牵涉到重新构建和部署服务端的一个新版本。

这样的单体服务器是构建这样一个系统最自然的方式。处理请求的所有逻辑都运行在一个单一进程中,允许你使用编程语言的基本特性将应用程序划分类、函数和命名空间。你认真的在开发机上运行测试应用程序,并使用部署管道来保证变更已被正确地测试并部署到生产环境中。该单体的水平扩展可以通过在负载均衡器后面运行多个实例来实现。

单体应用程序可以是成功的,但人们日益对他们感到挫败,尤其是随着更多的应用程序被部署在云上。变更周期被捆绑在一起 —— 即使只变更应用程序的一部分,也需要重新构建并部署整个单体。长此以往,通常将很难保持一个良好的模块架构,这使得很难变更只发生在需要变更的模块内。程序扩展要求进行整个应用程序的扩展而不是需要更多资源的应用程序部分的扩展。

Springboot与微服务翻译

图2: Conway法则在起作用

微服务采用不同的分割方法,划分成围绕业务能力组织的服务。这些服务采取该业务领域软件的宽栈实现,包括用户接口、持久化存储和任何外部协作。因此,团队都是跨职能的,包括开发需要的全方位技能:用户体验、数据库、项目管理。

Springboot与微服务翻译

对跨微服务的数据来说,去中心化责任对管理升级有影响。处理更新的常用方法是在更新多个资源时使用事务来保证一致性。这个方法通常用在单体中。

像这样使用事务有助于一致性,但会产生显著地临时耦合,这在横跨多个服务时是有问题的。分布式事务是出了名的难以实现,因此微服务架构强调服务间的无事务协作,对一致性可能只是最后一致性和通过补偿操作处理问题有明确的认知。

对很多开发团队来说,选择用这样的方式管理不一致性是一个新的挑战,但这通常与业务实践相匹配。通常业务处理一定程度的不一致,以快速响应需求,同时有某些类型的逆转过程来处理错误。这种权衡是值得的,只要修复错误的代价小于更大一致性下损失业务的代价。

基础设施自动化
在过去的几年中,基础设施自动化已经发生了巨大的变化,特别是云和AWS的演化已经降低了构建、部署和运维微服务的操作复杂度。

许多用微服务构建的产品或系统是由在持续部署和它的前身持续集成有丰富经验的团队构建的。团队用这种方式构建软件,广泛使用了基础设施自动化。如下面的构建管线图所示:

Springboot与微服务翻译

图6: 模块部署常常不同

为失效设计
使用服务作为组件的一个结果是,应用程序需要被设计成能够容忍服务失效。任何服务调用都可能因为供应者不可用而失败,客户端必须尽可能优雅的应对这种失败。与单体应用设计相比这是一个劣势,因为它引入额外的复杂性来处理它。结果是,微服务团队不断反思服务失效如何影响用户体验。Netflix的Simian Army在工作日诱导服务甚至是数据中心故障来测试应用程序的弹性和监测。

在生产环境中的这种自动化测试足够给大多数运营团队那种不寒而栗,通常在结束一周的工作之前。这不是说单体风格不能够进行完善的监测设置,只是在我们的经验中比较少见。

侧边栏:断路器和产品就绪代码
断路器(Circuit Breaker)与其他模式如Bulkhead和Timeout出现在《Release it!》中。这些模式是被一起实现的,在构建通信应用程序时,它们是至关重要的。这篇Netflix博文很好的解释了使用这些模式的应用程序。

既然服务随时都可能失败,那么能够快速检测故障,如果可能的话,能自动恢复服务是很重要的。微服务应用程序投入大量比重来进行应用程序的实时监测,既检查构形要素(每秒多少次数据请求),又检查业务相关指标(例如每分钟收到多少订单)。语义监测可以提供一套早期预警系统,触发开发团队跟进和调查。

这对微服务架构特别重要,因为微服务偏好编排和事件协作,这会带来突发行为。虽然很多专家称赞偶然涌现的价值,事实的真相是,突发行为有时可能是一件坏事请。监测对于快速发现不良突发行为是至关重要的,所以它可以被修复。

单体可以被构建成和微服务一样透明 – 事实上,它们应该是透明的。不同的是,你绝对需要知道在不同进程中运行的服务是否断开。对同一进程中的库来说,这种透明性是不大可能有用的。

侧边栏:同步调用被认为是有害的
任何时候,在服务间有大量的同步调用,你将遇到停机的乘法效应。简单地说,就是你的系统的停机时间编程各个组件停机时间的乘积。你面临一个选择,让你的调用变成异步或者管理停机时间。在www.guardian.co.uk,他们已在新平台实现了一个简单的规则 – 每个用户请求一个同步调用,而在Netflix,他们的平台API重设计成在API交换结构(fabric)建立异步性。

微服务团队希望看到为每个单独的服务设置的完善的监控和日志记录,比如控制面板上显示启动/关闭状态和各种各样的运营和业务相关指标。断路器状态、当前吞吐量和时延的详细信息是我们经常遇到的其他例子。

进化式设计
微服务从业者,通常有进化式设计背景并且把服务分解看做是进一步的工具,使应用程序开发者能够控制他们应用程序中的变更而不减缓变更。变更控制并不一定意味着变更的减少 – 用正确的态度和工具,你可以频繁、快速且控制良好的改变软件。

当你试图把软件系统组件化时,你就面临着如何划分成块的决策 – 我们决定分割我们的应用的原则是什么件的关键特性是独立的更换和升级的理念[13] – 这意味着我们要找到这样的点,我们可以想象重写组件而不影响其合作者。事实上很多微服务群组通过明确地预期许多服务将被废弃而不是长期演进来进一步找到这些点。

卫报网站是被设计和构建成单体应用程序的一个好例子,但它已向微服务方向演化。网站的核心仍是单体,但他们喜欢通过使用调用单体API构建的微服务添加新功能。这种方法对天然临时性的特性特别方便,比如处理体育赛事的专题页面。网站的这样一部分可以使用快速开发语言迅速的被放在一起,并且一旦赛事结束立即删除。在金融机构中,我们看到类似的方法,为一个市场机会添加新服务,并在几个月甚至几周后丢弃掉。

强调可替代性是模块设计更一般原则的一个特例,它是通过变更模式来驱动模块化的[14]。你想保持在同一模块中相同时间改变的事情。系统中很少变更的部分应该和正在经历大量扰动的部分放在不同的服务里。如果你发现你自己不断地一起改变两个服务,这是它们应该被合并的一个标志。

把组件放在服务中,为更细粒度的发布计划增加了一个机会。对单体来说,任何变更都需要完整构建和部署整个应用程序。而对微服务来说,你只需要重新部署你修改的服务。这可以简化和加速发布过程。坏处是,你必须担心一个服务的变化会阻断其消费者。传统的集成方法试图使用版本管理解决这个问题,但是微服务世界的偏好是只把版本管理作为最后的手段。我们可以避免大量的版本管理,通过把服务设计成对他们的提供者的变化尽可能的宽容。

微服务是未来吗br> 我们写这篇文章的主要目的是讲解微服务的主要思想和原则。通过花时间做这件事情,我们清楚地认为微服务架构风格是一个重要的思想 – 它值得为企业应用程序认真考虑。我们最近用这种风格构建了一些系统,也知道别人用这种风格并赞成这种风格。

那些我们知道的以某种方式开拓这种架构风格的包括亚马逊,Netflix,卫报,英国政府数字服务部门,realestate.com.au,前锋和comparethemarket.com。2013年的会议电路中全是正向微服务类别转移的公司 – 包括Travis CI。此外还有大量的组织长期以来一直在做可归为微服务类别的事情,但是还没有使用这个名字。(这通常被称为SOA – 虽然,正如我们说过的,SOA有许多矛盾的形式。[15])

尽管有这些积极的经验,但是,我们并不认为我们确信微服务是软件架构的未来发展方向。虽然到目前为止,与单体应用程序相比,我们的经验是正面的,但我们意识到这样的事实,并没有经过足够的时间使我们做出充分的判断。

通常,你的架构决策的真正后果是在你做出这些决定的几年后才显现的。我们已经看到对模块化有强烈愿望的一个好团队用单体架构构建的项目,已经衰败了多年。很多人相信微服务是不太可能出现这种衰败的,因为服务界限是明确的,并且很难围绕它打补丁。然而,知道我们看到经过足够岁月的足够的系统,我们不能真正评估微服务架构有多么成熟。

人们当然有理由希望微服务是多么不成熟。在组件化中做任何努力,成功取决于软件在多大程度上适用于组件化。很难弄清楚组件边界在哪里。进化式设计承认获取正确边界的困难性和使它们易于重构的重要性。但当你的组件是带有远程通信的服务时,那么重构它比重构带有进程内库的服务难很多。跨服务边界移动代码是很困难的,任何接口变更都需要在参与者之间进行协调,需要添加向后兼容层,并且测试也变得更加复杂。

侧边栏:《构建微服务》
我们的同事Sam Newman花费2014年的大部分时间写了一本书,捕捉了我们构建微服务的经验。如果你想深入到这个话题中,这应该是你的下一步。

另一个问题是,如果组件不组成的干净利索,那么所有你做的是将复杂度从组件内部转移到组件之间的连接。不仅仅是把复杂性移到周围,它将复杂性移动到一个不太明确、难以控制的地方。在没有服务间的凌乱连接的情况下,当你在看一个小的、简单的组件内部时,你可以很容易的认为事情是更好的。

最后,有团队技能的因素。更熟练的团队倾向于采用新技术。但是对更熟练的团队更有效的一种技术不一定适合于不太熟练的团队。我们已经看到大量的例子,不太熟练的团队构建了凌乱的单体架构,但这需要时间去看当微服务发生这种凌乱时会发生什么。一个差的团队总是创建一个差的系统 – 很难讲在这个例子中微服务会减少这种凌乱还是使它更糟糕。

我们听到的一个合理的说法是,你不应该从微服务架构开始。相反,从单体开始,使它保持模块化,一旦单体成为问题时把它分解成微服务。(虽然这个建议是不理想的,因为一个好的进程内接口通常不是一个好的服务接口。)

所以我们怀着谨慎乐观的态度写了这篇文章。到目前为止,我们已经看到关于微服务风格足以觉得这是一条值得探索的路。我们不能肯定地说,我们将在哪里结束,但软件开发的挑战之一是,你只能基于目前能拿到手的不完善的信息作出决定。

2011年5月在威尼斯召开的软件架构研讨会上,“微服务”这一术语被讨论用来描述参与者一直在探索的一种常见的架构风格。2012年5月,该研讨会决定使用“微服务”作为最合适的名字。2012年3月在波兰克拉科夫市举办的33届Degree大会上,James介绍了这些想法作为一个案例研究微服务 – Java,Unix方式,Fred George也差不多在同一时间提出。Netflix的Adrian Cockcroft把这种方法描述为“细粒度的SOA”,在网域级开拓了这一风格,还有在该文中提到的许多人 – Joe Walnes, Dan North, Evan Botcher 和 Graham Tackley。 ?

单体这一术语已被Unix社区使用了一段时间,在《Unix编程艺术》中用它来描述非常大的系统。 ?

很多面向对象的设计人员,包括我们自己,在领域驱动设计意义上使用服务对象术语,该对象不依赖于实体执行一个重要进程。这和我们在本文中如何使用“服务”是不同的概念。不幸的是,服务这个词有两个含义,我们不得不忍受这个多义词。 ?

我们认为应用程序是一个社会结构,它由代码基、功能组、资金体组合在一起。 ?

原文可在Melvyn Conway的网站上找到,在这里。 ?

在极端规模下,组织通常移至二进制协议并权衡规模的透明度。例如protobufs。使用二进制协议的系统仍旧展现出智能端点、哑管道。大多数网站,当然绝大多数企业不需要做这种权衡,透明度可以是一个很大的胜利。 ?

我们忍不住提起Jim Webber的说法,ESB全称是“令人震惊的意大利面条盒” ?

Netflix使这种联系清晰起来 – 直到最近作为细粒度SOA提及他们的架构风格。 ?

“YAGNI”也就是“You Aren’t Going To Need It(你将不需要它)”是一个XP原则和劝诫,在你知道你需要它们时才添加特性 ?

我们声称单体是单一语言的,这有一点不诚实 – 要在现在web上构建系统,你可能需要知道JavaScript、XHTML、CSS、选择的服务器语言、SQL和ORM方言。很难只用单一语言,但是你知道我的意思。 ?

在2013年11月的Flowcon大会上提交的这个出色演讲中,Adrian Cockcroft特别提到“开发者自助服务”和“开发者运行他们自己写的代码”(原文如此)。 ?

我们这里有一点不诚实。显然在更复杂的拓扑结构中部署更多的服务要比部署单一单体更困难。幸运的是,模式减少了这种复杂性 – 在工具上的投资仍是必须的。 ?

事实上,Dan North提到这种风格是可更换的组件架构而不是微服务。因为这似乎是在讨论我们更喜欢的后者的一个特征子集。 ?

Kent Beck强调这是他《实现模式》一书中的设计原则之一。 ?

SOA几乎是这段历史的根源。我记得当SOA这一术语出现在本世纪初时,有人说“多年来我们一直这样做”。一个理由是,这种风格看其根源是在企业计算早期COBOL程序通过数据文件通信的方式。在另一个方向,有人可能会说微服务和Erlang编程模型相同,但被应用于企业应用程序上下文

http://blog.cuicc.com/blog/2015/07/22/microservices/#fnref15

文章知识点与官方知识档案匹配,可进一步学习相关知识云原生入门技能树服务网格(istio)ServiceMesh介绍8770 人正在系统学习中

来源:reddingt0n

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年6月4日
下一篇 2020年6月4日

相关推荐