[.com原稿]在过去的四年里,使用微服务构建应用程序似乎已经成为一种标准。与我合作过的大多数团队也表现出不同程度的兴趣。微服务所承诺的弹性、高可用、低耦合和敏捷性,以及解决单体架构带来的问题的能力,是其流行的主要原因。但最近一段时间,一些关于微服务的保留意见和注意事项似乎引起了人们的注意。在这篇文章中,我想重点介绍一下微服务的应用,它有哪些缺点,以及在什么情况下应该慎重考虑使用微服务架构。什么是微服务在工业层面,对于微服务的基本特征的定义是比较一致的。这些特征可以概括如下:微服务是一种应用于组件设计(服务如何分组)和部署架构(服务如何部署和通信)的模式。微服务适合创建具有“一定功能复杂性”的分布式应用程序。个别服务必须很小。每个服务按功能划分,实现关注点分离。每个服务保持自治和相互解耦,并且可以独立部署、版本控制和扩展。服务通过轻量级API和异步通道的组合相互通信。每个服务都有自己的状态,只能通过服务本身访问。一个典型的微服务实现模式如下:图1:典型的微服务实现模式从上图我们可以看出:微服务中的每一组服务都有自己的前端(由一个API和一个可选的UI组件组成),一个实现自己的服务域逻辑和独立数据存储的域层。前院。将所有前端组件(UI组件或API)组合成一个连贯的前端(复合UI或API网关)。作为异步通信主干的事件总线。主要问题在于,对于适合微服务架构的用例,人们对微服务的看法趋于一致。这就是为什么我想采用相反的方法并尝试说明微服务可能不是最佳选择的情况。微服务的挑战程序员知道好处,但不知道成本。-RichHickey(Clojure设计师)实施微服务涉及权衡取舍。由于本文的重点不是抨击微服务的缺陷,因此尽量保持简短并切中要点。1.微服务很难正确设计有专门的书《Microservices AntiPatterns and Pitfalls》来记录它的缺陷。需要非常非常多的迭代才能得出令人满意的域设计。同时,几个基础的、结构化的问题没有直接的答案,往往需要调整和迭代,比如:关注点如何横向拆分,数据如何共享,数据以何种方式复制,如何管理报告,是否应将其包含在服务UI组件等中。2.微服务引入了复杂性微服务引入了一个已被充分记录的复杂性级别,其中最著名的是“微服务-不是免费的午餐”。图2:API数量翻倍微服务带来的挑战包括:API数量翻倍。这使得更改代码变得困难,并引入了版本控制的复杂性,从而难以分解服务的功能。引入了网络延迟。在组合服务时,在可伸缩性和增加的响应时间之间需要权衡。鉴于CAP理论,处理跨越多个服务的事务是复杂的。与具有单个数据库的单体架构不同,这些事务通常不由基础设施处理。调试分布式系统很复杂(参见“微服务——不是免费的午餐”)。异步系统、服务间锁和竞争条件中的错误可能很难定位和排除。虽然这些复杂性可以通过技术手段来克服,但这需要技术人员额外投入精力,无法让他们专注于实现那些更有价值的业务功能。3.微服务需要组织结构的转变微服务要求组织转向自治的跨职能团队。根据康威定律,这是至关重要的一步。这意味着前端和后端开发人员、数据平台工程师、QA、产品经理和运营人员必须在一个团队中协同工作。图3:微服务需要组织架构的转变。像这样的组织工作起来非常顺利。这是因为大部分的依赖都存在于团队内部,而且由于优先级相同,所以都很快解决了。4.微服务需要流程和实践的改变微服务需要流程和实践的改变。从偶尔发布几个主要版本,到经常发布许多较小的版本。从手动资源供应到资源供应的自动化形式,例如基础设施即代码。微服务架构的成功依赖于改变组织和流程的能力,这通常是最难的。图4:微服务需要流程和实践的改变5.微服务需要深度技术栈上面讨论的技术挑战意味着团队的技术集需要更全面地扩展。团队成员需要了解分布式系统、DevOps、基础架构即代码(IaC)、不同类型的数据库、前端组件化和组合、单元测试、全自动发布、迭代、小版本发布计划、测试工具、多版本管理etc.什么时候不应该使用微服务1.应用太小应用太小不适合微服务。当然,这个应用程序可能会在未来增长,直到将整个字段添加到其中。在这种情况下,当接近RoI阈值时,将使用微服务。那些较小的团队也是如此。图5:代码行数与维护成本2.领域不明确领域不明确或不确定,导致领域模型不确定。例如,当产品被描述为“门户”时,当你开始创业并准备构建一个应用程序时,当一个CRM系统管理订单甚至有邮政投递时,这个问题就会凸显出来。在这种情况下,整体式结构更加灵活。晚上,当您独自将CRM域转换为逻辑解决方案时,您可能会惊讶于利用IDE进行重构和单元测试套件的安全性是多么容易。3.组织不能改变组织不能改变以适应微服务。它还包含数据组、前端组、后端组等。康威定律倾向于将服务组合成分层的微服务架构。大家可以对比一下图1和图6。图6:传统组织形式做微服务因为不同的团队有不同的优先级,导致跨团队的依赖环环相扣,造成延迟和冲突。4.缺乏理解团队缺乏对微服务概念、DDD或概念设计的经验和理解。虽然这可能并不重要,但您应该仔细阅读文档并向有经验的人寻求建议。糟糕的架构设计的产物往往是一个高度耦合的分布式“单体架构”系统,随之而来的所有问题:网络通信和延迟、复杂性、隐藏的依赖关系以及部署过程中的耦合等。我们大多数人都喜欢学习新事物,但并非所有人都这样做,学习需要时间和精力。有时,在您学到一些东西之前,您必须不断犯错误,包括大错误。在某些情况下,甚至有必要废弃原始版本并从头开始。这些是在做出决定之前必须考虑的潜在成本。管理层也需要尽早习惯重构,在某些极端情况下甚至接受从头开始一个项目。经常失败。早点失败。快速失败。拥抱失败是成功的一种方式。不要害怕失败,学会接受失败。——GaryBurnison,光辉国际首席执行官接受失败并不是一件容易的事,因为沉没成本往往会误导你下一步的决策。5.其他团队不成熟,技术栈不适合微服务或离职率高。因为系统的无序度(熵)会随着时间的推移不断增加,代码的可维护性也会随着时间的推移而降低。由于更复杂的系统更难维护,这可能会加剧第3.4条提出的问题。困惑和压力常常使人们退缩到他们熟悉的圈子里。他们会“偷工减料”来解决问题,或者走捷径来避免复杂性。很快,由此产生的软件架构可能会被技术组件、“核心”库、服务到服务引用、编排器,甚至“CSV导入服务”污染,然后开始进入彼此的数据库。接下来,有人问“我们应该如何编排部署来管理服务之间的依赖关系?”这无异于软件版本地狱,这种系统也被称为分布式“单体架构”。图7:运行和调试组件依赖项的复杂性会降低开发的整体效率。跨服务的错误调查和日志分析很复杂。这就产生了一个问题,就是这些工作只能交给团队中那些技术经验比较丰富的成员。但这些成员关注的重点应该是如何维护系统的长期稳定运行,而不是救火。简而言之,在这种情况下,微服务不会带来优势,反而会让整个团队为负面结果买单。你应该如何选择?所有软件系统都可以分解为两个主要元素:策略和细节。策略元素包含所有业务规则和程序。策略是系统真正的价值所在。这些细节对于使人类、其他系统和程序员能够与策略进行通信是必需的,但这些细节都不会影响策略的行为。详细信息包括IO设备、数据库、Web系统、服务器、框架、通信协议等。架构师的目标是为系统创建一个形状。此配置文件将策略视为系统中最重要的元素,同时使细节与策略无关。这允许延迟和推迟有关细节的决定。-RobertC.Martin,CleanArchitecture如果你正在构建的应用程序有一个相当清晰的领域,将来会发展到相当大的规模,那么在项目开始时就会部署一个庞大的团队,并且你对团队的能力有信心技术,你对分布式设计有一定的经验或者至少有一定的素养,同时你能得到管理层对失败和学习的支持和包容,那么微服务会是一个不错的选择。但请注意,有时微服务在布局时会适得其反。如果您处于与前面描述的场景类似的场景中,那么从一些更简单的体系结构开始可能是明智的。例如单体架构或分层架构(它本身可能包含一些专门的服务)。微服务架构可以解决的问题,大部分也可以通过其他方案来解决。松散耦合、可扩展和前瞻性的系统来自设计良好的应用程序架构。此类架构往往具有明确定义的边界和专用数据存储。微服务只能通过提供物理约束来满足这种场景。另一种创建物理约束的方法是通过组件(DLL、JAR)。组件架构和部署架构的选择应尽可能深思熟虑。容器和基础架构即代码(IaS)可以与微服务架构一起使用。事实上,它们通常更容易实施,因为网络很简单,配置量也不那么重要。同时,容器还可以让环境的搭建和销毁变得更加容易,可以加快开发环境的部署。构建自动化和频繁发布可以通过增加关注和减少在制品(ReducedWIP)、小批量(SmallBatches)、原子变更流(AtomicChangeFlow)和减少协作来实现。对于复杂的分布式系统,微服务无疑是一个不错的选择。但微服务并不是唯一的选择。微服务的吸引力往往会驱使人们决定采用它们,而忽略了它带来的各种问题。人们应该考虑各种选择,以便做出有意识的、有教养的和理性的选择。作者简介邱仁波,拥有多年运营商和数据中心数据库业务分析经验。目前在市图书馆信息技术部工作。每日关注国内外极客新闻,前后端技术。海外知识搬运工。【原创稿件,合作网站转载请注明原作者和出处为.com】
