当前位置: 首页 > 科技观察

你需要模块,而不是微服务-剖析为什么每个人都在谈论微服务

时间:2023-03-21 12:15:01 科技观察

架构有时很困难,人们不断提出新想法,但在没有任何背景或细微差别的情况下很快就消失了它已经成为主流的“做事方式”。业界渴望找到改进架构的方法,毫不犹豫地抢购了这些新想法。微服务是这些新想法的最新体现,现在是我们剖析这个新想法并找到正在发生的事情的真正根源的时候了。微服务在微服务的核心,我们被告知我们会发现......许多好东西:可扩展性:代码可以分解成更小的部分,可以独立开发、测试、部署和更新。专注:开发人员专注于解决业务问题和业务逻辑。可用性:后端数据必须始终可供各种设备使用。简单性:简化大型企业应用程序的开发。响应能力:使分布式应用程序能够扩展是对不断变化的事务负载的响应。可靠性:通过提供在发生故障时可以继续运行的复制服务器组来确保没有单点故障。在失败后将正在运行的应用程序恢复到可用的良好状态。这些词听起来都很耳熟,但这六句话的有趣之处在于,其中两句来自微服务文献(博客文章、论文等),两句来自20年前的EJB文献,两句来自Oracle燕尾服(40多年前的技术)。你能看出它是从哪里来的吗?在我们的行业中,有一种趋势是一遍又一遍地重复使用我们的卖点。“那些不记得过去的人注定要重蹈覆辙。”--GeorgeSantanyana,TheLifeofReason(1905)1905)关于微服务炒作,公司博客文章(https://www.integrella.com/expertise/microservices/)提供了进入微服务的10个理由:数据最佳实践。微服务非常适合“面向数据管道”的架构,它与大数据的收集、摄取、处理和交付方式保持一致。数据管道中的每个步骤都以微服务的形式处理一个小任务。它们相对容易构建和维护。它们的单一用途设计意味着它们可以由较小的团队构建和维护。每个团队都可以跨职能,同时也专注于解决方案中的微服务子集。他们支持更高质量的代码。将整个解决方案模块化为离散组件有助于应用程序开发团队一次专注于一小部分。这简化了整个编码和测试过程。它们简化了团队间的协作。与通常涉及重量级进程间通信协议的传统“面向服务的体系结构”(SOA)不同,微服务使用事件流技术来简化集成。它们支持实时处理。微服务架构的核心是一个“发布-订阅”框架,它允许实时数据处理以提供即时输出和洞察力。它们促进快速增长。微服务通过模块化架构实现代码和数据重用,从而更轻松地部署更多数据驱动的用例和解决方案以增加业务价值。他们推动更多的输出。数据集通常以不同的方式呈现给不同的受众;微服务简化了为各种最终用户摄取数据的方式。在应用程序生命周期中更容易评估更新。高级分析环境(包括用于机器学习的分析环境)需要方法来评估现有的计算模型以及新创建的模型。微服务架构中的A-B和多变量测试使用户能够验证他们更新的模型。它们有助于扩展。可扩展性不仅仅是处理更多容量的能力。这也与投入其中的努力有关。微服务可以更轻松地识别扩展瓶颈,然后在每个微服务级别解决这些瓶颈。有许多流行的工具可用。大数据世界中的各种技术(包括开源社区)在微服务架构中运行良好。ApacheHadoop、ApacheSpark、NoSQL数据库和许多流分析工具都可以用于微服务。让我们花点时间研究一下上述每个问题:它们促进了大数据最佳实践。管道和过滤器架构(Pipes-and-filters)自70年代以来一直是软件领域的一部分,“Unix哲学”提倡的理念是:a)让每个程序做好一件事。做一份新工作,重建而不是通过添加新“功能”使旧程序复杂化。b)期望每个程序的输出是另一个未知程序的输入。不要用无关信息混淆输出。避免严格的柱状或二进制输入格式。不要坚持交互式打字。它们相对容易构建和维护。请参阅上面的“Unix哲学”。他们支持更高质量的代码。如果一次专注于一小部分有助于提高质量,请参阅上面的“Unix哲学”。它们简化了团队间的协作。这个很有趣;它建议“面向服务的架构,通常涉及重量级进程间通信协议”——比如JSONoverHTTP?或者这是否意味着所有SOA都需要全套SOAP、WSDL、XMLSchema和WS-*规范?具有讽刺意味的是,微服务绝不会阻止它使用任何这些“重量级”协议,一些微服务甚至建议gRPC,一种更类似于IIOP的二进制协议,从CORBA开始,它是“重量级协议”SOAP完整集合的前身、WSDL、XMLSchema和WS-*规范。它们支持实时处理。实时处理实际上已经存在了很长时间,虽然其中许多系统是使用发布-订阅或“事件总线”模型实现的,但很少需要微服务来实现。它们促进快速增长。“复用模块化架构”,我们能算出有多少不同的东西以“复用”为卖点吗?编程语言当然已经做到了(OOP、函数式语言、过程式语言)、库、框架……总有一天,希望看到一些炒作的技术,明确地说“去他的重用,我们才不关心那些”。他们推动更多的输出。“数据集通常以不同的方式呈现给不同的受众”——这听起来很像CrystalReports主页。在应用程序生命周期中更容易评估更新。对于机器学习和高级分析的背景,需要“根据新创建的模型评估现有的计算模型”……听起来像是一堆动作词,但背后几乎没有实质内容。它们有助于扩展。多么有趣——EJB、事务性中间件处理(如Tuxedo)和大型机都是这样宣传的。有许多流行的工具可用。对于我们行业中的每一次重大炒作,工具总是可用的——尤其是在炒作持续一段时间之后。大多数读者的年龄还不足以记住CASE工具,但也许他们会记住UML。但眼光敏锐的读者会注意到,上面的一半观点有一个相当共同的主题:创建和维护小的、独立的代码和数据“块”的想法,彼此分开,使用共同的输入和输出来启用更大的系统集成。就像……在微服务的核心,我们发现……模块。微服务vs模块是的,低级“模块”,这是自1970年代以来大多数编程语言的核心概念。(甚至更早,尽管这在没有模块作为第一级核心概念的旧语言中很难做到。)CLR(c#、f#、VisualBasic等)上的“assembly”,JVM(Java、Kotlin、Clojure、Scala、Groovy等)上的“jar”或“package”,或来自您最喜欢的operation系统的动态链接库(Windows上的dll,*nixes系统上的sos或as,当然macOS在/Library目录下有“frameworks”隐藏),但在概念层面上,它们都是模块。它们都有不同的内部格式,但都有相同的基本目的:独立构建、管理、版本控制和部署的可重用代码单元。考虑以下模块的工作定义,引用自计算机科学基础论文(https://www.win.tue.nl/~wstomv/edu/2ip30/references/criteria_for_modularization.pdf):“项目工作标准系统的划分保证了系统的模块化,每个任务形成一个独立的、不同的程序模块,在执行时,每个模块及其输入输出是明确的,并且在与其他系统模块的预定接口方面没有歧义。检查时,独立测试模块的完整性;检查开始前同时完成多个任务的调度问题很少;最后,以模块化方式维护系统;系统错误和缺陷可以追溯到特定系统模块,从而限制了详细错误搜索的范围”。定义明确的“独立、独特的程序模块”涵盖了微服务建议的一半好处,并且已经这样做了50年。那么为什么微服务会引起这样的骚动呢?因为微服务从来都不是关于微服务、服务,甚至分布式系统。在微服务的核心,我们应该找到……组织清晰度。组织清晰亚马逊是最早公开讨论微服务概念的公司之一,事实上他们并不是要推动架构原则,而是一个几乎没有障碍的独立开发团队的想法。需要等待DBA团队对数据库结构进行更改?QA需要构建来测试以便他们可以发现错误?还是等待基础架构团队采购服务器?还是等待UX团队为演示创建原型?您听到的声音是开发团队对任何和所有这些依赖项的总体所有权,这些依赖项可能(并且经常)阻碍他们的进步。这意味着这些团队是普通IT团队各个部分(分析、开发、设计、测试、数据管理、部署、管理等)的缩影。这确实意味着今天的团队要么必须由不同技能的组合组成,要么我们必须要求每个团队成员都具备全套技能(所谓的“全栈开发”),这意味着要雇用这些人变得无限棘手。这也意味着团队现在要对自己的生产中断负责,这意味着团队自己现在有随叫随到的责任(以及随之而来的工资和法律问题)。但是当所有这些都得到处理时,这意味着每个团队都可以独立地构建他们的工件,除了时间的物理限制和手指在键盘上飞行的速度之外没有任何限制。至少在理论上。在微服务的核心,我们经常发现……分布式计算的谬误。(参见:《使用微服务前必须要了解的“分布式系统的谬误”》)分布式计算的谬误对于那些不熟悉它们的人来说,这个谬误最早是PeterDeutsch在1980年代给Sun同事的报告中提出的。它们再次出现在AnnWolrath和JimWaldo1994年的开创性论文《A Note on Distributed Computing》中,它们基本上都说了同样的话:“让分布式系统正确——性能、可靠性、可伸缩性,无论“正确”意味着什么——都很难。”“获得正确的分布式系统(性能、可靠性、可扩展性,无论“正确”意味着什么)都很难。”就内存模块而言,即使在50年前,跨进程或库边界传递数据的成本也几乎可以忽略不计。然而,当通过网络线路传递数据时——正如大多数微服务所做的那样——会给通信增加5到7个数量级的延迟。这不是我们可以简单地通过向网络添加更多节点来“横向扩展”的问题;它实际上使问题变得更糟。是的,我们可以将所有微服务放在一台主机上,并通过这种方式降低一些问题的相关性。但通常是通过将它们加载到运行单个微服务容器镜像的虚拟机集群中。(例如,使用DockerCompose或Kubernetes来托管Docker容器。)但是,这样做会增加虚拟机进程边界之间的延迟(因为我们必须根据七层规则在虚拟网络堆栈中上下移动数据模型,即使其中一些层是完全模拟的),并且仍然存在在单个节点上运行的可靠性问题。更糟糕的是,当我们开始与分布式计算的谬误搏斗时,我们开始遇到一组相关但独立的问题:企业计算的谬误(http://blogs.newardassociates.com/blog/2016/enterprise-computing-fallacies.html)。在微服务的核心,我们需要……重新思考我们真正需要的是什么。您是否需要将问题分解为单独的实体?您可以通过在Docker容器中包含托管的独立进程、在遵循标准化API约定的应用程序服务器中包含独立模块或通过各种其他选项来实现这一点。这不是放弃任何已经构建的技术的问题——它可以使用过去20年中来自任何地方的技术来完成,包括servlets、ASP。NET、Ruby、Python、C++,甚至是令人毛骨悚然的Perl。关键是建立一个具有易于理解的集成和通信约定的通用架构背板,无论您想要或需要它是什么。您是否需要减少开发团队面临的依赖性?然后开始查看这些依赖关系,并与合作伙伴一起确定可以将哪些依赖项引入团队。如果组织不想正式打破其组织结构图的“以技能为中心”的本体论(意味着您有一个“数据库组”、一个“操作组”和一个“测试组”作为“开发组”的对等组"),然后与高级管理人员合作,至少允许采用“虚线”报告结构,以便每个小组的个人现在“矩阵化”到一个团队中。但是,最重要的是,确保团队对他们要构建的东西有清晰的认识,并且他们可以自信地向街上的任何陌生人描述他们的服务/微服务/模块的核心。关键是给团队方向和目标、完成任务的自主权以及完成任务的号角。参考资料:http://blogs.newardassociates.com/blog/2023/you-want-modules-not-microservices.html文章来自:热爱科学的Wesley,如需转载本文,请联系Wesley今天谁热爱科学头条号。