你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
适用于此 Azure Well-Architected 框架性能效率清单建议:
| PE:06 | 通过在类似生产的环境中定期测试来优化工作负荷的性能,以确保工作负荷达到所需的性能目标并实现业务目标。 |
|---|
性能测试是一种非功能测试做法,用于评估工作负荷在不同条件下的行为方式。 它有助于尽早识别性能下降,主动解决问题,并确保继续与服务级别协议保持一致。
测量响应时间、吞吐量、资源使用情况和稳定性时,可以收集工作负载一致满足定义的目标并交付业务所需的性能级别的证据。
本文中的关键策略建立在OE:09 测试的架构策略中描述的基础测试实践之上。 建议先查看该文章。 本指南中的建议的范围是性能,并专注于实现性能目标,以便工作负载与不断发展的业务目标保持一致。
下表定义了本文中使用的关键性能术语。
| 术语 | Definition |
|---|---|
| 性能目标 | 工作负荷必须满足的特定性能值,例如响应时间、吞吐量或并发用户数。 |
| 性能阈值 | 将可接受的性能与给定指标的不可接受的性能分开的边界。 |
| 性能预算 | 分配给工作负荷的每个层或组件的总体性能目标部分。 |
| 错误预算 | 错误或故障的允许级别,源自 SLO。 |
| 接受条件 | 测试结果必须满足的条件才能使工作负荷通过其性能要求。 |
| 假设驱动的试验 | 一种测试方法,用于声明有关性能的预测、针对基线对其进行测试,并使用测量的结果对其进行验证。 |
| 性能基线 | 一组指标,表示通过测试验证的正常条件下工作负荷的行为。 |
| 合成事务 | 模拟实际用户交互的脚本请求,以在受控条件下测量系统性能。 |
| 性能回归 | 与已建立的基线相比,性能下降,由代码、配置或基础结构的更改引入。 |
| 性能偏差 | 随着时间的推移,性能逐渐下降,如果没有定期与已建立的基线进行测试,往往会被忽视。 |
为性能测试设置可衡量的目标
可衡量的性能目标将主观期望转化为可测试和验证的目标标准。
定义性能目标并分配预算。 定义并记录特定的性能目标,例如需要支持的并发用户数。 确保这些目标与服务级别目标(SLO)保持一致,并将其转换为可衡量的测试目标。
在工作负载的不同层分配性能和错误预算。 如果性能测试失败,预算将帮助你确定哪个层负责,以及优化工作的重点位置。 如果没有预算,失败的测试只会告诉你性能目标得不到满足,而不是问题所在。
例如,可为 API 响应时间设置 400 毫秒的预算、150 毫秒的数据库查询,以及失败请求的 1% 上限。 测试失败时,可以根据其预算检查每个层的结果,以确定问题是 API 响应速度缓慢、数据库查询缓慢还是错误峰值。
注释
在了解用户流和性能要求之前,请避免定义 SLO。 SLO 应基于实际用户需求和业务目标,而不是任意目标。
定义具有明确通过和失败阈值的验收条件。 根据性能指标(例如延迟、响应时间、吞吐量、资源利用率、错误率和与性能目标相符的任何其他性能指标)来制定验收条件。
为每个指标定义阈值,使测试产生明确的通过或失败结果。 如果 SLO 要求在 200 毫秒内完成 95 个请求%,请在第 95 百分位将 API 响应时间阈值设置为 200 毫秒。 第 95 百分位超过 200 毫秒的任何测试运行都失败。
提前开始并持续测试
早期性能分析能在体系结构瓶颈变得代价高昂之前发现并解决它们。
在工作负荷的软件开发生命周期中尽早开始性能测试。 无需完整的应用程序即可开始。 开发人员可以在本地分析代码、测量响应时间并确定资源密集型操作。 早期测试会告知设计决策,根据性能目标验证体系结构选择,并确定优化机会。
随着工作负荷的发展,不断测试工作负荷以满足新的要求。 每个代码更改都可能会引入性能回归。 定期运行测试以尽早捕获这些更改。 在部署管道中整合性能测试,并运行定期的自动化测试,以便在性能漂移影响到生产环境之前检测到它。
权衡。 早期性能测试需要专用的基础设施和专业知识,从而提高运营成本。 将此投资与迟发现的性能问题和生产事故的成本相平衡。
在实际条件下进行测试
性能测试应与实际条件匹配,以便结果有意义。
镜像生产环境
测试环境应尽可能接近生产。 根据您的工作负荷的风险配置文件调整方法以适应环境。
对于任务关键型工作负荷,请完全匹配生产:
- 计算 SKU 和配置
- 自动缩放设置
- 缓存配置
- 网络条件(延迟、带宽)
- 外部依赖关系
对于非关键工作负荷,在模拟生产的缩减环境中进行测试可以提供低成本的有用见解。
防止配置偏差。 配置偏移可能导致误导性测试结果。 实现自动检查以验证测试环境是否与生产环境匹配。 在运行测试之前,请确保部署正确的版本。
权衡。 用于性能测试的完整生产环境复制显著增加了基础设施成本。 评估在生产环境中出现性能问题的风险是否值得为您的工作负载专门建立性能测试基础设施的成本。
验证生产中的性能
测试环境无法完全复制影响性能的实际条件。 生产测试暴露出仅在实际使用情况下出现的问题,并为将来的优化提供准确的基线。 某些性能要求只能在实际用户、数据和基础结构相交的地方进行验证。
运行受控的生产测试。 在非高峰时段安排测试,以了解您的工作负荷在资源耗尽的情况下表现以及如何从故障中恢复。
生产测试显示实际条件下的性能特征,包括:
- 现实的用户行为模式和数据量
- 真正的网络延迟和带宽变化
- 地理分布效果
- 第三方 API 性能和依赖项
- 实际缓存行为和基础结构特征
使用渐进式测试技术。 从少量流量开始,逐渐增加。 监视每个步骤的响应时间、吞吐量、错误率和资源利用率。 这种逐步方法会限制风险,同时识别断点、揭示瓶颈,以及根据不断增长的需求提供系统行为的准确视图。
持续监视生产测试 ,以尽早发现问题。 实现自动化安全措施,以便在测试对用户造成负面影响时停止测试,例如自动回滚机制和实时警报。 这些技术可确保快速响应并最大程度地减少中断。
注释
在生产环境中运行受控性能测试时,需要分配额外的容量来处理测试生成的附加负载。
风险: 生产测试直接影响实际客户,因为它可以创建额外的负载并中断流量。 始终实施安全措施、限制暴露,并准备好回滚计划,以最大程度地减少潜在的业务影响。 在权衡实际测试带来的好处与可能对实时用户造成中断的业务影响之间找到平衡。
使用假设驱动的试验验证更改
使用假设驱动的试验来指导性能测试。 设计单个性能试验,以便它们产生有意义的结果。
从有关工作负荷性能的集中假设开始,并定义可衡量的成功标准,这些标准可导致可操作决策。 例如,假设可能是:“向订单表添加索引可缩短 70% 高峰负载下的查询时间。基线是当前架构,变体是具有新索引的架构。 针对这两个版本运行相同的负载测试。 捕获查询延迟、数据库 CPU 使用情况和吞吐量,然后比较结果以确定假设是否成立。
权衡。 假设驱动的试验需要针对基线和变体配置运行相同的测试,这会增加基础结构成本和测试执行时间。 将试验集中在高影响变化上,其中潜在的性能提升可证明额外的测试工作合理。
应用多个性能测试类型
性能测试涵盖一系列测试,用于评估各种条件下的速度、稳定性和可伸缩性。 每个测试类型都针对工作负荷的不同性能方面。 它可发现独特的见解,并实现超出功能测试的完整评估。
使用多个测试类型从不同角度验证工作负荷。 例如,压力测试在峰值负载下查找断点,但只有持久性测试才能揭示经过数小时或数天后浮现的内存泄漏。
根据需要验证的内容选择测试类型。
下表显示了何时使用每个测试类型,以及它揭示您工作负载的信息。 虽然此表不是详尽列表,但它作为一个说明性示例。
| 测试类型 | 主要用途 | 何时应用 | 它显示的内容 | Environment |
|---|---|---|---|---|
| 负载测试 | 验证系统在正常和高峰使用情况下处理预期的用户负载 | 提前启动,频繁运行 | 基线性能、容量限制、缩放有效性 | 过渡或类似于生产的环境 |
| 压力测试 | 了解系统限制和断点 | 在系统准备进入生产环境之前 | 最大容量、故障模式、恢复行为 | 专用性能测试环境 |
| 峰值测试 | 确保系统处理突发流量高峰 | 提前启动,尤其是面向公众的应用 | 自动缩放响应能力、队列处理、正常降级 | 预生产或生产环境 |
| 耐力/浸泡测试 | 检测仅在较长时间内出现的问题 | 初始负载测试通过后 | 内存泄漏、资源耗尽、连接池问题 | 具有完整资源分配的生产型环境 |
不要立即尝试实现所有测试类型。 首先进行基本的负载测试,以了解基线性能。 当你识别风险并获得经验时,请扩展到压力测试、峰值测试和最终耐力测试。
权衡。 跨所有测试类型的性能测试需要大量的时间和基础设施投资。 将测试投资与业务风险相匹配。
使用实际使用模式和数据特征
使用实际数据进行测试可提供对资源消耗、系统行为和隐藏性能问题的准确见解。
创建表示各种方案、用户配置文件和数据卷的各种测试数据集。 使用输入变体和随机化来模拟真实用户多样性。 包括可能导致性能问题的边缘情况,例如大型有效负载、复杂查询或高并发性。
测试数据应类似于实际生产数据。 使用具有生产数据特征的合成数据。 为某些方案预留生产数据集(经过正确匿名处理),例如突出显示数据管理行为,如事务一致性、数据量处理和延迟。
模拟模拟真实用户工作流的合成事务。 编写这些事务的脚本并重复运行这些事务,以生成反映工作负荷实际使用方式的负载。
测试方案应反映实际使用模式,例如并发用户访问、高峰负载周期和特定事务序列。 确保方案符合业务目标,以便性能结果反映真正的用户价值。
在负载下测试时,请包括实际的第三方 API 调用。 模拟外部依赖项使测试运行更快、更可预测,但它隐藏了实际性能问题。 如果应用依赖于支付处理器 API,请使用实际调用进行测试,以了解端到端延迟。
使用测试结果指导设计决策
测试结果通过建立可靠的基线和指导优化工作来推动设计决策。
建立基线度量。 基线可帮助你识别趋势和异常情况,以及优化更改是否提供改进。 需要可靠的基线来跟踪一段时间内的性能趋势。
在初始测试期间记录性能指标。 此录制是您的参考基线,是“正常”性能的快照。 在后续运行中,将新结果与此基线进行比较,以检测性能更改。 检查数据以了解各种条件下的系统行为时,请考虑用户影响、频率、修复成本以及更改条件的风险。 查找显示性能下降位置的模式。 使用此见解确定优化工作的优先级。
优化是一个迭代过程,应由数据驱动。 在开发周期中预留专用时间进行性能优化。 使用基线来衡量更改的影响,并确保它们提供预期的改进,而无需引入回归。
将性能与业务指标相关联。 将性能改进与收入、用户参与度、客户满意度和转换率等业务成果联系起来,以证明持续在性能优化方面的投资是正当的。
注释
在对工作负荷进行重大更改后定期查看和更新基线,例如体系结构更改、新功能或缩放调整。 通过执行此操作,可确保性能目标保持相关。
使测试资产与当前使用模式保持一致
性能测试资产包含有关工作负荷的预期行为、可接受的性能阈值和实际流量模式的关键知识。
按类型组织测试套件。 在单独的套件中保留负载测试、压力测试和耐力测试。 不要混合它们。 每种类型都有不同的设置要求、运行持续时间和成功条件。 组织套件可以更轻松地运行目标测试、跨运行比较结果以及独立维护每个套件。
定期刷新测试数据。 过时的测试数据会导致不切实际的结果。 重新生成测试数据,以在数据模型发生更改、数据量增长或用户人口统计变化时反映当前生产数据特征。
随着工作负荷的发展,请查看测试方案。 计划定期评审,以确保方案仍反映实际使用情况。 方案已过时,如下所示:
- 用户行为随时间变化
- 随着用户群的增长,流量模式发生变化
- 新功能引入了不同的使用模式
- 基础设施扩展以满足新的容量需求
Azure 便利化
Azure Pipelines使你能够将性能测试集成到 CI/CD 管道中。 可以在管道中添加负载测试,以验证应用程序的性能和可伸缩性。
Azure Chaos Studio可帮助将实际故障注入应用程序,以便可以运行受控的故障注入试验。 这些试验可帮助你衡量、了解和改进云应用程序和服务复原能力。
Azure 负载测试 是一种负载测试服务,用于在任何应用程序上生成大规模负载。 负载测试提供自动执行负载测试并将其集成到持续集成和持续交付(CI/CD)工作流的功能。 可以定义测试条件,例如平均响应时间或错误阈值,并根据特定的错误条件自动停止负载测试。 负载测试提供一个仪表板,用于在负载测试期间提供 Azure 应用程序组件的实时更新和详细的资源指标。 可以分析测试结果,识别性能瓶颈,并比较多个测试运行,以了解随时间推移的性能回归。
Azure Monitor是一种全面的监视解决方案,用于从云和本地环境收集、分析和响应遥测数据。 Application Insights 是监视器的扩展,提供 APM 功能。 可以在开发和测试期间以及生产环境中使用 Application Insights 监视应用程序。
相关链接
性能效率清单
请参阅完整的建议集。