当然,IT专业人士应该对微服务等被炒作的技术进行批判性的审视[1]、[2]、[3]、[4]。最后,对于一个特定的项目来说,只有有利或无利的选择。特定项目中的个别优势和劣势应该是重点。毕竟,选择对项目没有帮助的酷的方法几乎没有意义。从一开始就排除不酷的方法也同样没有意义,尽管它们可能会解决一个特定的问题。
但是,炒作并不只是发生。为了更好地理解好处,追溯炒作的源头是有意义的。要做到这一点,首先看一下微服务时代之前的情况。那时,只有部署单体。其中一些单体的代码量很大,单是编译有时就需要10或20分钟,而且需要很长时间才能启动应用程序。再加上单元和其他测试的时间。至于测试,应用程序可能要启动几次。在某些时候,富有成效的工作几乎是不可能的,因为程序员要等很久才能看到他们的工作成果。
如果你实际开发和测试代码,这样的时间是难以接受的。改变需要的时间太长了。然后是与其他系统或复杂的运行环境(如应用服务器)的复杂集成。它们必须被配置,这就进一步延长了周期,使生产的道路更加困难。
在我第一次关于微服务的谈话中,我问听众,他们是否知道部署单元过大的项目或部署单元过小的项目。似乎有很多项目的部署单元过大,但实际上几乎没有部署单元过小的项目。至少在那个时候,减少部署单位的规模当然是有意义的。
起源
维基百科[5]是关于微服务的炒作起源和历史的一个很好的来源。据此,在2011年的一次软件架构研讨会上,一些与会者描述了一种新的架构风格。2012年,在这个系列的下一个研讨会上,发明了 "微服务 "这个词。与会者包括,例如,Adrian Cockcroft(Netflix)、James Lewis(ThoughtWorks)和Fred George(自由职业者)。这三个人都已经有了很多的经验,并且正在进行重要的项目工作。他们选择微服务方法当然不是为了制造新的炒作,而是为了解决实际问题。
他们项目中的具体问题是相似的,但也有区别。例如,虽然云战略对Netflix非常重要,但对其他项目来说,情况并不那么强烈。有些项目需要扩展,但有时是在不同的领域:扩展团队规模或将软件扩展到多个服务器。
解决方案也不同。Netflix依赖于同步通信和服务,其规模大到整个团队都在忙于开发。而弗雷德-乔治则推荐异步通信和微服务,其规模不超过几百行,可以非常容易地重写。
所以,从来没有一个真正的微服务概念,而是从一开始就有不同的方法来解决不同的问题。即使在今天,微服务方法的解释和实施仍然非常不同。
模块
但是,微服务到底是什么?就其核心而言,微服务是一种不同的模块,并与JARs、Maven项目或Java命名空间等模块化方法竞争。像图1中的分区可以作为微服务来实现--或者用不同的模块化方法。
图1:应用程序的模块可以是微服务--或其他类型的模块。
微服务和其他选项之间有很大区别。
- 在一个部署单体中,可能会发生你在其他包的新代码中使用一些现有的类。这可能会在包之间产生一种实际上并不想要的依赖关系。这种依赖性不是故意的。它甚至可能没有被注意到,因为它隐藏在代码中,包之间的依赖关系并不明显。这就导致了在一段时间后,部署的单体有大量不需要的依赖关系。当然,一个架构管理工具,比如说,可以避免这种情况。但如果没有采取任何预防措施,架构中的依赖性混乱是不可阻挡的。另一方面,如果模块是微服务,它们通过一个明确的接口,例如通过REST,相互通信。所以,你必须使用接口明确地引入从一个微服务到另一个微服务的依赖关系。这可以防止依赖关系因为你错误地使用了某些类而悄悄出现。
- 对于操作来说,各个模块是可见的,因为它们是独立的进程。另一方面,在一个部署单体中,所有的模块都被安置在一个进程中。这意味着,除了部署,其他的操作方面,如度量和安全,都可以面向单个模块。
由于微服务提出了对系统进行合理划分的问题,微服务使模块重新成为讨论的核心。这就产生了模块化单体的想法,因为部署单体也可以被划分为模块。它甚至应该被模块化,毕竟,一个没有模块的系统几乎不可能被维护。如果说微服务的炒作促成了模块作为一个基本的架构概念再次受到重视,这已经很有价值了。如果不同的模块化方法之间有一个权衡,那就太好了。
这提出了一个重要的问题。如果这么多部署单体的结构都很差,为什么下一个部署单体的结构要好一些呢?问题的关键不是要否定一般的部署单体是不好的。毕竟,有_一些_ 结构良好的部署单体。但是对于大量结构不良的部署单体,你必须提出并回答这个问题--例如,通过使用架构管理工具。微服务的优势在于,至少分区是强制执行的。
领域驱动的设计
当然,问题是如何实现对模块的合理划分。像松散耦合这样的良好分区的特征是众所周知的--但要实现它们却不是那么容易。一种可能性是DDD。
领域驱动设计(DDD)[6]在2005年左右经历了它的第一次绽放。当时,它被认为是面向对象系统设计的指南。类成为资源库、服务、实体或聚合体。DDD有助于在类的层面上对系统进行精细化设计。
但这个领域只是DDD的一个部分,即战术设计。如今,人们更关注的是战略设计。这涉及到将系统划分为有边界的上下文。一个有界限的上下文有自己的领域模型,与其他领域模型分开。例如,可能有一个领域模型用于订单交付,另一个用于支付。这两个领域模型是完全不同的:例如,支付是关于支付选项、客户的信用度,或者商品的价格和税率。对于交付,重点是物流服务提供商、客户的交付地址,或货物的尺寸或重量。以货物为例,很明显,领域模型有具有相同标签的领域对象,但对这些领域对象的不同方面进行建模--在一个有边界的环境中是价格和税率,在另一个环境中是尺寸和重量。
这种粗粒度的模块化和解耦可能是微服务所带来的最重要的趋势。拥有数百张表的数据库,每张表都有许多列,这表明领域模型已经变得过于复杂,需要被拆分。这就是有边界的上下文可以帮助的地方。当然,如果根本没有使用微服务,这也适用。所以,微服务也启动了这个领域的讨论,它与微服务以外的领域相关。
长期的架构
许多系统的存活时间比最初计划的要长。因此,系统的构建方式必须使其在长期内保持可维护和可扩展性。通常情况下,团队试图定义和执行 "干净 "的架构。许多项目开始时都有这样的考虑。然而,最终成功使用这些概念来创建一个长期可维护的系统的项目数量很少。尝试一下不同的方法也许是有意义的。
有时,建筑师试图确定变化的焦点,然后以灵活的方式实施。但对变化频率的估计只能基于历史数据。然而,未来在原则上是很难预测的。架构往往在完全错误的地方具有灵活性,这只会不必要地增加系统的复杂性。在那些真正被改变的地方,灵活性是缺失的。最后,系统就更难改变了。
一种不同的方法可以通过微服务来实现。根据有界限的上下文进行的功能划分是最基本的。支付和交付货物将永远是电子商务系统的一部分。如果情况不再如此,软件转换可能仍然是最小的问题。从功能的角度来看,这种划分可以长期保持稳定。DDD的目标根本不是长期稳定,而是功能上的正确划分。但这也许是实现长期可维护性的最佳方式。
然而,对于技术来说,还必须有一种方法来保持系统的长期适应性。毕竟,一个项目所选择的任何技术迟早会被淘汰。在某些时候,将没有更多的安全更新,迁移到一个新的技术成为必须。系统应该被划分为小单元,可以独立迁移到一个新的技术版本或新的技术。这样一来,就可以避免大规模的、有风险的技术更新。
在其他领域,也有结合新旧技术的成功方法。模块化合成器由模块组成,可以组合起来产生声音。模块的一个标准是Eurorack[7]。它定义了模块之间的通信,例如控制模块和计时,当然还有音频信号。该标准还定义了操作的各个方面,如模块的大小和电源电压。该标准自1996年以来一直存在,现在有5000个模块,其中一些是完全不同的,所有这些都可以组合。当然,这些模块有时使用的技术在1996年--差不多25年前--还不存在。现代和旧技术可以毫无问题地结合起来。
微服务允许采用类似的方法。一个微服务系统只需要将通信标准化--例如,用REST或用消息传递系统。此外,操作必须由适当的规则来保证。例如,微服务可以作为Docker容器来实现,并有标准化的指标或日志接口。
因此,微服务系统可以实现异构的技术栈,因为任何技术都可以在Docker容器中使用。这支持更新到新的技术:可以为每个单独的微服务逐步进行更新。这种方法降低了风险:如果新技术有困难,它们只发生在已经被更新的微服务中,你可以先从单个微服务开始。对于不值得更新的微服务,不必迁移到当前的技术,这样可以节省时间和精力。
只有在异质技术栈可能的情况下,这样的逐步迁移才能发挥作用。然而,这只是微服务的情况,所以对技术更新的更好支持是一个关键的区别。
持续交付
软件的持续交付[8]有明显的优势。例如,如果软件是定期交付的,生产中的变化要快得多。因此,进入市场的时间就会提高。同时,一项研究[9]证明,还有很多优点。例如,经常部署的团队可以更快解决服务故障。由于部署也代表了服务的重建,这个结果并不那么令人惊讶。同样不令人惊讶的是,当你经常部署的时候,部署失败的频率更低。毕竟,不仅是部署的变化更小,而且团队有更多的部署实践。
但持续交付还有其他好处。经常部署的团队将50%的时间投入到新事物上,而其他团队只有30%的时间。作为回报,他们在安全问题、错误或终端用户支持方面的工作更少。持续交付提高了团队的生产力。研究表明,拥有持续交付的公司在市场上更成功,员工的倦怠感也更少。产生这些好处的原因大概是,通过提高部署速度,软件开发过程中的现有问题变得很明显,然后可以被优化掉。此外,在频繁部署的情况下,必须明确在什么条件下会将变化投入生产。此外,这个过程必须易于执行和可靠。这样的环境对员工来说也是比较愉快的。
该研究还显示了团队应该多长时间部署一次。表现较差的团队一个月到半年部署一次,而表现优秀的团队则每天部署几次。
一个每季度部署一次的项目应该改为每天部署多次,以利用持续交付的许多积极作用。在一个例子中,开发阶段之后是十周的测试,然后在周末进行发布。在这种情况下,如果通过自动化将测试速度提高100倍,例如,他们仍然需要4小时。部署仍然需要两个小时,在加速了四倍之后。那么你将需要6个小时的部署时间。如果要每天部署几次,仍然需要达到2或3的系数。图2显示了所需时间的关系。
图2:必须大规模提高释放速度
由于所需的极端加速因素,很难想象只关注现有流程的优化和自动化的策略会带来预期的成功。事实上,所引用的研究表明,需要在各个领域进行改进,以提高部署的速度。其中一个措施是解耦架构。微服务是这方面的一个方法。如果不把它们分割成可单独部署的模块,每天进行几次部署的目标似乎很难实现,尽管它有如此多的积极作用。单纯的自动化和优化很难将测试的速度提高那么多。但如果你改变架构,使系统的一部分可以单独测试和部署,问题就会变得容易解决。
这个场景也表明,微服务的整个部署管道必须是独立的--包括特别是测试。如果架构被微服务所取代,但保留了单体测试方法,那么就没有什么变化。
持续交付表明,孤立的微服务并不能解决所有问题,但优化是可能的,例如通过自动化。另一方面,只有当系统被划分为可单独部署的单元(如微服务)时,才能实现复杂系统的高部署速度。
组织结构
微服务是一种架构方法,但它们也会产生组织影响。传统的组织通常根据技术技能组合来组建团队,如UI团队和后台团队。
然而,康威法则指出,系统的架构会复制通信结构。相应地,这种划分会导致一个UI组件和一个后台组件。这并不符合DDD所宣扬的功能划分。这就是为什么在微服务世界中存在逆康威手法。特定领域的组件,如有界的上下文,被分配给一个团队。这样,组织在团队中遵循目标的面向领域的架构。当然,如果没有微服务,这样的方法也是可以想象的。但是,微服务在受限上下文的功能独立性上增加了技术独立性。每个微服务可以与其他微服务分开部署,并使用其他技术**(图3**)。
图3:微服务用技术独立性补充了有界上下文的领域独立性。
除了微服务和逆康威手法,还有几种方法,它们的核心都是一样的。
- DDD要求由一个团队来开发Bounded Context。战略设计不仅描述了Bounded Context的关系,还描述了可能的团队关系。
- 敏捷性要求跨职能的团队。这些团队应该拥有尽可能多的技能,以便他们能够尽可能地独立工作。他们还应该自己组织起来,并尽可能自己做出更多的决定。
- 基于DevOps研究的 "加速"[10]一书,建议采用松散耦合的架构来扩展团队。团队应该选择工具。重点需要放在开发人员和结果上,而不是技术或工具。微服务可以支持这一点,因为它们是松散耦合的,每个微服务可以使用不同的技术。然而,其他方法也是可以想象的。
微服务并没有引入组织和架构属于同一的想法,但是这个想法被不同的领域带入了角色。
微服务可以使独立和自我组织的团队成为可能。尽管有微服务,团队的行动能力可能会受到限制。信任团队是很重要的。只有这样,他们才能被允许为自己做决定。这方面也许比把架构换成微服务更重要。
当然,除了扩大组织规模,还有很多其他使用微服务的理由。所以绝不是说微服务只对大型复杂的系统有意义,但由于持续交付方面的优势,它们在小型项目中也可以发挥作用。
总结
微服务被炒得沸沸扬扬,但它已经消停了,变成了相反的情况。无论你是否使用微服务,微服务已经改变了关于架构的讨论。
- 模块和领域驱动设计又成了重要的话题。这很好,因为合理的模块化是系统可维护性的核心。
- 对于一个长期存在的架构,微服务提供了一个很好的选择,因为异构的技术栈。
- 持续交付是优化软件开发的一个重要途径。至少在某些情况下,只有将微服务作为一种架构概念,才能实现必要的部署速度;但微服务只是应该采取的众多优化措施之一。
- 组织和架构之间的关系不仅被微服务带入焦点。
- 因此,微服务提供了一些有趣的思考,即使没有完整的微服务架构也是有用的。因为归根结底,这不是追逐炒作,而是要做出明智的架构决策。
链接和文献
[1] Wolff, Eberhard: "Microservices:灵活的软件架构,microservices-book.com/
[2] Wolff, Eberhard: "微服务入门",microservices-book.com/primer.html
[3] Wolff, Eberhard: "Microservices - A Practical Guide",practical-microservices.com/
[4] Wolff, Eberhard: "Microservices Recipes",practical-microservices.com/recipes.htm…
[5]en.wikipedia.org/wiki/Micros…
[6] Evan, Eric: "Domain-Driven Design Referenz",www.domainlanguage.com/ddd/referen…
[7]en.wikipedia.org/wiki/Eurora…
[8] Wolff, Eberhard: "A Practical Guide to Continuous Delivery",continuous-delivery-book.com/
[9]cloud.google.com/devops/stat…
[10] Forsgren, Nicole; Humble, Jez; Kim, Gene: "ACCELERATE
精益软件和DevOps的科学:建立和扩展高绩效的技术组织",IT革命出版社,2018年
The postMicroservices after the hypeappeared first onDevOps Conference.