点 Redis 8 发布了——而且它是开源的

了解更多

微服务架构核心概念

微服务在创建应用程序中扮演什么角色?我们将为您提供对微服务是什么、它们与单体结构有何不同以及在评估是否采用微服务时应考虑的事项的基础理解。 

微服务架构是一个框架,它表示工作流或流程的不同部分,通常涉及业务的一个领域。例如,以一个零售应用程序为例,它涉及购物车、订单管理、支付、结账、产品目录、后端财务/会计集成以及客户服务支持。这些服务是解耦的,代表了不同的知识领域,尽管它们确实需要相互交叉才能形成一个功能齐全的微服务应用程序。

独立自主的软件开发团队管理、测试和部署这些解耦服务,而不会影响整个系统的其余部分。这些独立但相互连接的服务的结果是一个可以作为更大架构运行的框架。如果实施得当,这种分块化可以通过允许团队创建自己的发布周期、加快生产速度以及通过简化操作与可重用组件来缩短上市时间,从而使操作更加灵活。

微服务架构 vs. 单体架构

单体是一个巨大的单一单元。想象一下澳大利亚的艾尔斯岩(其原住民名称“Uluru”意为“巨大的单体”)、大狮身人面像或米开朗琪罗的《圣母怜子》。关键是:单体通常是庞大的结构。

同样,单体架构是将整个应用程序的所有不同业务单元连接到一个共享相同代码库的单一堆栈中。这种结构使得难以独立地扩展任何单独的组件。例如,考虑一个发布网站,用户非常频繁地请求文章,但相比之下,新文章的发布频率较低。在单体架构中,您无法有效地将文章阅读与发布隔离开来并进行扩展。 

微服务架构将分割不同的业务领域,允许独立团队选择他们认为持续成功发布所需的技木栈。

微服务架构特性

微服务使团队能够扩展其整个应用程序,并通过无需整体堆栈大修的更新更快地响应客户需求。这些是一些定义开发人员如何构建微服务的关键特性。 

服务独立性和自主性

在任何公司中,每个业务单元都有自己的一套与特定应用程序相关的业务挑战和目标。在大多数情况下,每个开发团队都有自主权选择工具、技术和资源来帮助他们在其限定上下文中完成工作范围。这种架构与多语言技术栈完美契合,因此开发人员在构建微服务应用程序时拥有充足的灵活性,可以按照他们想要的方式来满足性能、可用性、持续发布周期和自动化测试目标。 在微服务中,“领域的主人”这句格言尤其适用,因为每个团队都按功能划分,并最终对其构建的内容负责。创建模块化团队在整个微服务应用程序内处理特定服务有助于加快上市时间

一个成功的实践是领域驱动设计,它鼓励开发人员深入理解他们的领域,从而使软件开发服务于用户的需求。在这种情况下,用户不总是其他人;其他相关服务也需要得到服务。虽然一个开发团队可能拥有很大的自主权,但它确实需要与其他开发团队无缝协作。 

各部分必须契合在一起,并且需要一致的接口。许多公司实施去中心化治理,通常在主题专家(SME)的帮助下,如企业架构师,以确保软件在整个组织中保持合规。

实用建议:尽早建立容错策略

有时,大型微服务应用程序的一部分会发生故障。即使将松耦合的功能作为多个微服务部署,保持通信线路畅通也非常重要。如果单个微服务发生故障,微服务架构需要在代码级别实现一个回退行为来应对这种中断。否则,“轻微”的故障可能会对所有其他微服务产生多米诺骨牌效应

故障可能由多种原因引起,从服务器不可用到数据库无法访问。幸运的是,有一些方法可以规避这些挑战。其中包括:复制实例、在请求上添加超时,以及使用采用容错设计模式来增强微服务应用程序的弹性。无论如何,在设计微服务时,都要假定事情会在最糟糕的时候发生故障——理想情况下,只有一个组件会发生故障。

实用建议:保持领域松耦合

根据计算机科学家 Melvin Edward Conway 提出的康威定律:“任何设计系统的组织(广义定义)所产生的系统设计结构,都会与其组织的沟通结构相同。” 预期您的技木栈会反映您公司的组织方式,并将这一点纳入您的设计流程。

特别是,尽最大努力使微服务架构中的系统尽可能地松耦合。您不希望某个元素的设计、实现或行为的改变导致另一个元素的改变。修改一个微服务以强制要求所有与其直接或间接协作的其他微服务几乎立即发生变化,这是一个糟糕的主意

如果多个微服务是基于组织层面的重度依赖关系构建的,那么领域就会失去自主性,随之失去产生自己发布周期的能力。找到正确的平衡点非常重要。 

通过 API 和消息进行通信

单体架构和微服务架构之间的服务间通信方法大不相同。在单体应用程序中,组件很难独立扩展,并且高度耦合。微服务是松耦合的,它们可以使用不同的服务间通信机制来交换信息,例如 REST API 或某种类型的消息队列系统。 

单体架构已经包含所有组件协同工作,可能还有一个或两个主数据库。每个微服务都有自己的实例,并且它们不一定共享相同的数据存储;这是领域驱动设计和多语言持久化的一部分——您可以为每个微服务选择合适的数据存储。  

微服务使用同步或异步通信,这意味着组件等待回复(同步)或不等待(异步)。同步通信场景的一个例子是用于验证登录和密码的身份验证服务;该服务需要响应才能允许用户进入基于微服务的应用程序。 

另一方面,异步通信不受时间约束,发送服务不需要另一个或多个服务回复。例如,在电子商务中,当客户结账时,您希望他们继续处理其他事情。他们不需要等待您处理订单、接收付款并最终完成订单。这一切都是异步完成的,客户通过通知(应用内推送通知、电子邮件或订单状态页面)了解进度。

实用建议:API 设计和服务注册中心

通常,您可以使用消息代理进行服务间的异步通信,但重要的是使用的消息代理不会增加系统复杂性,并且如果它无法随着消息增长而扩展,可能导致延迟。

版本化您的 API:持续记录您对每个服务进行的属性和更改。“无论您使用 REST API、gRPC 还是消息传递……”,Sylvia Fronczak 为 OpsLevel 写道,“模式会发生变化,您需要为此做好准备。” 一个典型的模式是将 API(应用程序编程接口)版本嵌入到您的数据/模式中,并优雅地弃用较旧的数据模型。例如,对于您的服务产品信息,请求者可以请求特定版本,并且该版本也会在返回的数据中注明。

减少闲聊,提升性能:同步通信会在服务之间产生大量的来回交互。如果确实需要同步通信,这对于少数微服务来说尚可,但当涉及数十甚至数百个微服务时,同步通信可能会导致扩展停滞。执行微服务审计,确定哪些地方需要同步通信,哪些地方不需要。异步方法,例如使用消息代理,将有助于减少依赖性,提高整体容错能力,并缓解性能迟缓。

记录每次更改(并保持整洁):服务注册中心是一个清单,记录了所有可用实例的位置(例如,通过 IP 地址)。IP 地址是不固定的——它们可以快速变化,从一分钟到下一分钟——所以要记录系统及其更改。

更积极地内置安全性

《微服务安全实战》(Microservices Security in Action)的作者 Prabath Siriwardena 和 Nuwan Dias 指出,单体应用程序只有少数几个入口点。但采用微服务架构编写的应用程序提供了更多入口点。“随着系统入口点数量的增加,攻击面也随之扩大,”他们写道。“这种情况是构建微服务安全设计的根本挑战之一。每个微服务的每个入口点都必须以相同的强度进行保护。系统的安全性不强于其最薄弱环节的强度。”

编写安全代码对于即使是最微不足道的应用程序也很重要,但在微服务架构中更是如此。攻击面越广,攻击风险越高。

书的作者指出,与单体应用程序不同,每个部署的微服务都必须执行独立的安全性检查——这会影响性能。 

实用建议:设置安全参数,

在受控环境中测试沙盒是一个安全受控的环境,开发人员可以在代码投入生产之前进行测试。这对于安全性测试很重要,也有助于您发现服务间连接中的问题。  

使用 Kubernetes 部署?使用 Operator:Kubernetes 是部署容器化应用程序和启动额外微服务实例的流行选择,但需要 DevOps 进行大量的配置才能正确部署和保护。拥有特定软件组件(例如数据库)的 Level III Kubernetes Operator 可以帮助自动化和安全部署。即使是帮助将敏感信息与应用程序代码分开的Kubernetes Secret,也未加密地存储在 API 的数据存储中,任何有权在该同一命名空间中创建 Pod 的人都可以轻易访问。

接下来是什么?

希望以上内容能为理解微服务的基本概念提供一个不错的入门指南。我们讨论了微服务架构与单体应用程序有何不同,两种模型下软件开发团队如何沟通,以及微服务为开发人员带来的自主性,以及如何通过适当的 API 设计实践来加强数据的最佳实践。

如果您刚开始接触微服务架构,请阅读我们的5 个微服务误解文章,以帮助您避开应用程序开发中最常见的微服务陷阱。