@levinzhang
2020-02-02T07:50:22.000000Z
字数 1928
阅读 1038
by
Kamil Grzybek认为,我们通常之所以会实现微服务架构是因为我们相信它能够解决单体应用中的所有问题。但是,我们应该关注架构驱动力,以便于寻找系统的最佳架构。在一个系列文章,他已经开始描述模块化单体的基本概念以及导致特定架构的驱动力。
通过观察IT社区正在发生的事情,Kamil Grzybek认为大多数新项目都是采用微服务架构实现的。但是,他认为IT行业正在犯一个错误,即我们采用微服务仅仅是因为我们相信它们能够解决单体应用中的所有问题。与之相反,Grzybek推荐我们关注架构驱动力(architectural driver),他强调每种架构都有其优点和缺点,都会解决一些问题,但是会带来新的问题。在一个系列文章,他已经开始描述模块化单体的基本概念和属性,以及导致特定架构的驱动力。
Grzybek是位于华沙的ITSG Global的架构师和团队领导,他首先指出术语单体系统和单体架构通常用来描述所有的组成部分都放到一个部署单元的系统,但是这些术语通常也会假定其所有的组成部分是相互交织在一起的,而不是由架构上独立的组件所组成,这些组成部分互相连接、互相依存,而不是松耦合的。他认为这是一个非常负面的描述,并不是单体的终极属性。相反,他将单体定义为单纯有且仅有一个部署单元的系统。
为了实现模块化,进而实现模块化的架构,Grzybek指出必须要有独立且可替换的模块,每个模块必须要有定义好的接口并实现接口所描述的功能需要的全部内容。一个模块从来都不是完全独立的,它总会依赖其他的东西。但是,依赖要尽可能匹配该原则:松耦合,强内聚。为了确定模块的独立性和可替换性,我们必须要关注三个元素:依赖的数量、这些依赖的强度以及它所依赖的模块的稳定性。
系统中的变更通常针对的是业务功能,而不是技术部分。因此,模块应该从业务的角度提供完整的特性集,以便于更加自治和独立。它还应该有一个定义良好的接口,也就是一个定义模块能够做什么的契约,并将它是如何实现的隐藏和封装起来。Grzybek提到,封装是模块化不可分割的一个元素。
架构驱动力指的是对架构有着重要影响的需求集,Grzybek在这个定义中参考了Michael Keeling。Grzybek将驱动力分成了四个主要的类别:功能性需求定义了系统要解决什么问题以及如何解决;质量属性定义了质量,比如可维护性和可扩展性;技术约束是关于工具限制、团队经验和技术标准的;最后,业务约束则是关于预算、硬性截止时间的。
Grzybek强调所有的架构驱动力都是彼此关联的,过于关注其中的某一个,往往会导致顾此失彼。他认为,系统的软件架构师就是要在不同的驱动力之间不停地做出选择,Grzybek指出,并没有预先定义好的正确方案,并不存在所谓的银弹。
在对比模块化单体和微服务架构时,一个常见的架构驱动力就是复杂程度。Grzybek发现模块化单体要比分布式系统复杂程度更低。高复杂性会降低可维护性、可读性和可观察性。它也会需要更有经验的团队、更高级的基础设施和特定的组织文化。如果简单性是一个关键的架构驱动力的话,那么他强烈建议团队要首先考虑单体形式并参考Martin Fowler的文章:单体优先。
在文章中,Grzybek还讨论了其他的驱动力,包括生产力、可部署性、性能、故障影响和异构技术,对于每种驱动力,他都给出了样例以及该驱动力对不同类型架构的影响。
Grzybek最后强调:
系统架构的形状会受到各种因素的影响,一切都取决于我们所在的上下文。
去年年底,Grzybek发布了一个开源项目,在该项目中,他详细阐述了如何使用领域驱动设计(Domain-Driven Design,DDD)的方式去设计、实现一个单体应用。他的目标是通过这个项目展示如何以模块化的方式设计和实现单体应用。
在柏林举行的microXchg 2019年会议上,Jan de Vries主张在使用微服务之前先构建一个单体。
在Reactive Summit 2018会议上,Randy Shoup在一次演讲中描述了以增量式架构方式构建系统,他声称我们应该从一个简单的架构开始,并随着需求的增加而不断演化。
在2015年的一篇博客文章中,Stefan Tilkov认为微服务的主要好处是在系统的不同部分之间创建了清晰且严格的边界。他反对微服务体系结构始终应该从单体开始的观点,他认为先构建一个具有清晰分割的具有良好结构的单体应用,随后再将其转换成微服务是极其困难的,甚至是根本不可能的。
查看英文原文:Modular Monolithic Architecture, Microservices and Architectural Drivers