你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

针对简单性和效率进行设计的建议

适用于此 Azure 架构良好的框架可靠性清单建议:

RE:01 设计工作负载,使其符合业务目标,并避免不必要的复杂性或开销。 使用实用且平衡的方法制定提供所需结果的设计决策。 将你的设计包含在必要条件中,以减少效率低下和潜在问题。

本指南介绍了将不必要的复杂性和开销降到最低的建议,以保持工作负载的简单高效。 选择最佳组件来执行必要的工作负荷任务,以优化工作负荷的可靠性。 为了减轻开发和管理负担,请利用平台提供的服务的效率。 此设计可帮助你创建可复原、可重复、可缩放且可管理的工作负荷体系结构。

定义

术语 定义
工作负荷 可以逻辑上与其他任务分开的离散功能或计算任务。

关键设计策略

设计可靠性的关键原则是使事情保持简单高效。 将工作负荷设计重点放在满足业务需求上,以减少不必要的复杂性或过多开销的风险。 请考虑本文中的建议,帮助你就设计做出决策,以创建精简、高效且可靠的工作负荷。 不同工作负荷在可用性、可伸缩性、数据一致性和灾难恢复方面可能有不同的要求。

必须根据业务需求来证明每个设计决策的合理性。 这种设计原则似乎很明显,但对于工作负荷设计至关重要。 应用程序是否支持数百万用户或几千个用户? 是否存在大型流量突发或稳定的工作负载? 可接受的应用程序中断级别是什么? 业务要求驱动这些设计注意事项。

权衡:复杂的解决方案可以提供更多的功能和灵活性,但它可能会影响工作负荷的可靠性,因为它需要更多的协调、通信和管理组件。 或者,更简单的解决方案可能无法完全满足用户期望,或者随着工作负荷的发展,它可能对可伸缩性和可扩展性产生负面影响。

与利益干系人协作进行设计练习

与利益干系人合作:

  • 定义并分配工作负荷的用户流和系统流的关键级别。 将设计重点放在关键流,以帮助确定所需的组件和实现所需复原级别的最佳方法。

  • 定义功能性和非功能性要求。 考虑功能要求来确定应用程序是否执行任务。 请考虑使用非功能要求来确定应用程序执行任务的方式。 确保了解可伸缩性、可用性和延迟等非功能要求。 这些要求影响设计决策和技术选择。

  • 将工作负荷分解为组件。 在设计中确定简单性、效率和可靠性的优先级。 确定支持流所需的组件。 某些组件支持多个流。 确定组件从概念上解决的难题,并考虑从单个流中删除组件,以简化整体设计,同时仍提供完整功能。 有关详细信息,请参阅执行失败模式分析的建议

  • 使用故障模式分析 来识别单一故障点和潜在风险。 考虑是否需要考虑不太可能的情况,例如遇到影响该区域所有可用性区域的重大自然灾害的地理区域。 成本高昂,涉及重大权衡,以缓解这些不常见的风险。 清楚地了解企业对风险的容忍度。 有关详细信息,请参阅执行失败模式分析的建议

  • 为流定义可用性和恢复目标 ,以通知工作负荷的体系结构。 业务指标包括服务级别目标(SLO)、服务级别协议(SLA)、平均恢复时间(MTTR)、故障平均时间(MTBF)、恢复时间目标(RTO)和恢复点目标(RPO)。 定义这些指标的目标值。 本练习可能需要在技术和业务团队之间达成妥协和相互理解,以确保每个团队的目标都符合业务目标,并且是现实的。 有关详细信息,请参阅有关定义可靠性目标的建议

支持更简单的设计选择

无需利益干系人参与即可执行以下建议:

  • 努力在设计中简单明了 。 对组件和服务使用适当的抽象和粒度级别。 避免过度工程或工程不足的解决方案。 例如,如果将代码分解为多个小型函数,则很难理解、测试和维护。

  • 承认所有成功的应用程序都会随时间而变化,无论是修复 bug、实现新功能还是技术,或者使现有系统更具可缩放性和复原能力。

  • 尽可能使用平台即服务(PaaS)选项 ,而不是基础结构即服务(IaaS)。 IaaS 就像有一盒零件。 你可以构建任何东西,但必须自己组装。 PaaS 选项更易于配置和管理。 无需设置虚拟机 (VM) 或虚拟网络。 你也不必执行维护任务,例如安装修补程序和更新。

  • 使用异步消息传送 将消息生成者与使用者分离。

  • 分清基础结构与域逻辑。 确保域逻辑不会干扰与基础结构相关的功能,例如消息传送或持久性。

  • 将跨领域问题转移到单独服务上。 最大程度地减少跨不同函数重复代码的需求,首选使用定义完善的接口来重用服务,这些接口可由不同组件轻松使用。 例如,如果多个服务需要对请求进行身份验证,则可以将此功能移到其自己的服务中。 然后,可以改进身份验证服务。 例如,可以添加新的身份验证流,而无需触摸任何使用该流的服务。

  • 根据需求评估常见模式和做法 的适用性。 避免遵循可能不适合你的上下文或要求的趋势或建议。 例如,微服务并不是每个应用程序的最佳选项,因为它们可能会带来复杂性、开销和依赖项问题。

开发足够多的代码

简单性、效率和可靠性的原则也适用于开发实践。 在松散耦合的组件化工作负荷中,确定组件提供的功能。 开发流以利用该功能。 请考虑以下针对开发做法的建议:

  • 满足业务需求时,请使用平台功能。 例如,若要卸载开发和管理,请使用云提供商提供的低代码、无代码或无服务器解决方案。

  • 使用库和框架。

  • 将配对编程或专用代码评审会话作为开发实践引入。

  • 实现标识 死代码的方法。 对自动化测试未涵盖的代码持怀疑态度。

选择正确的数据存储

过去,许多组织将其所有数据存储在大型关系 SQL 数据库中。 关系数据库为关系数据事务提供原子、一致、隔离和持久(ACID)保证。 但这些数据库存在缺点:

  • 查询可能需要高开销的联接。

  • 需要规范化数据,并在写入时根据架构重新构建这些数据。

  • 锁争用可能影响性能。

关系数据库的替代方案

在大型解决方案中,单个数据存储技术可能不满足所有需求。 关系数据库的替代方案包括:

  • 键值存储

  • 文档数据库

  • 搜索引擎数据库

  • 时序数据库

  • 列系列数据库

  • 图形数据库

每个选项都有利弊。 不同的数据类型更适合不同的数据存储类型。 请选择最适合你的数据及其使用方式的存储技术。

例如,可将产品目录存储在支持灵活架构的文档数据库(例如 Azure Cosmos DB)中。 每个产品说明都是一个独立文档。 若要查询整个目录,可为目录编制索引,并将索引存储在 Azure 认知搜索中。 产品清单可能会进入 SQL 数据库,因为该数据需要 ACID 保证。

建议

  • 请考虑其他数据存储。 关系数据库并不总是合适的。 有关详细信息,请参阅 “了解数据存储模型”。

  • 请记住,数据不仅仅包括持久化的应用程序数据。 还包括应用程序日志、事件、消息和缓存。

  • 采用使用数据存储技术组合的多面体持久性或解决方案。

  • 考虑现有的数据类型。 例如,存储:

    • SQL 数据库中的事务数据。

    • 文档数据库中的 JSON 文档。

    • 时序数据库中的遥测数据。

    • Azure 认知搜索中的应用程序日志。

    • Azure Blob 存储中的 Blob。

  • 确定可用性与一致性的优先级。 CAP 定理意味着必须在分布式系统中的可用性和一致性之间进行权衡。 无法完全避免网络分区,这是 CAP 定理的其他组件。 但可以采用最终一致性模型来实现更高的可用性。

  • 考虑开发团队拥有的技能组合。 使用混合持久性有一些好处,但也有可能适得其反。 它需要新的技能集才能采用新的数据存储技术。 若要充分利用技术,开发团队必须:

    • 优化查询。

    • 针对性能做出优化。

    • 使用适当的使用模式。

选择存储技术时,请考虑以下因素:

  • 使用补偿事务。 使用 polyglot 持久性,单个事务可能会将数据写入多个存储。 如果出现故障,请使用补偿事务撤消已完成的任何步骤。

  • 考虑边界上下文,这是一个域驱动设计概念。 界限上下文是指域模型周围的明确边界。 边界上下文定义模型应用于的域的哪些部分。 理想情况下,界限上下文将映射到业务域的子域。 请考虑对系统中的有限上下文使用 polyglot 持久性。 例如,产品可能显示在产品目录子域和产品清单子域中。 但很可能这两个子域在存储、更新和查询产品方面有不同的要求。

Azure 便利化

Azure 提供以下服务:

  • Azure Functions 是一种无服务器计算服务,可用于使用最少的代码生成业务流程。

  • Azure 逻辑应用是一个无服务器工作流集成平台,可用于使用 GUI 或编辑配置文件生成业务流程。

  • Azure 事件网格是高度可缩放的完全托管的发布-订阅消息分发服务,提供使用 MQTT 和 HTTP 协议的灵活消息使用模式。 使用事件网格,可以使用设备数据生成数据管道,生成事件驱动的无服务器体系结构,并集成应用程序。

有关详细信息,请参阅:

示例

有关根据要求确定组件及其功能的示例工作负荷,请参阅 Reliable Web App 模式

可靠性清单

请参阅完整的建议集。