---
schema_version: "1"
id: 3a0c783ecbe877a683b281fecd6d13eeda0bc7b143595393b6a36ce185136159
title: 卓越运营 - DevOps 模式
collection: architect
version: current
locale: zh-cn
portal_url: https://docs.salesforce.com/architect/current/zh-cn/well-architected/guides/operational-excellence-devops-patterns.md
canonical_url: https://architect.salesforce.com/docs/architect/zh-cn/well-architected/guide/operational-excellence-devops-patterns.html
source_site: architect.salesforce.com
content_type: documentation
content_hash: eaaf39f769deb94fdc584954139faa8b401ff6328937c73b354ed587d5240b7e
products:
  - 架构良好的框架
  - Architect Site Content Repo
---
# 卓越运营 - DevOps 模式

<br>

了解有关架构良好的[卓越运营](/docs/architect/zh-cn/well-architected/guide/operational-excellence.html)的更多信息 → [DevOps 实践](/docs/architect/zh-cn/well-architected/guide/operational-excellence.html#devops-practices)

## 源驱动的开发

**模式**

| 何处查看 | 好样的 |
| --- | --- |
| 版本控制设置    | ✅ 所有元数据以 Git 源格式存储，使用 Salesforce DX 项目结构，其中 .forceignore 配置为排除不相关的文件；所有团队成员从中央存储库复制 |
| 临时组织使用情况        | ✅ 开发人员从源创建用于功能工作的临时临时组织，将更改提交回版本控制，并在功能完成后丢弃临时组织 |
| 提交消息          | ✅ 每个提交都包含清晰、简洁的消息，解释发生了什么变化及其原因；消息遵循团队约定（例如，“feat:”、“fix:”、“docs:”）。 |
| 变更跟踪          | ✅ 版本控制中捕获的每个元数据修改都带有作者身份、时间戳和显示精确更改的差异 |
| 代码审核流程      | ✅ 所有生产绑定更改都通过合并前需要审核批准的拉取请求进行；声明性配置接受与代码相同的检查 |
| 回滚程序      | ✅ 以前的版本可以通过 Checkout 或还原操作从 Git 历史中恢复；团队记录了在非生产环境中测试的回滚程序 |
| 审计跟踪              | ✅ 在版本控制中保留完整的更改历史，支持合规要求和安全调查 |
| 分支策略       | ✅ 与团队规模和发布频率相适应的一致的 Git 分支模型（GitFlow、GitHub 流或基于中继）；已记录并强制执行 |
| 从基于组织的迁移 | ✅ 在解决方案生命周期的早期完成向源代码驱动的开发的过渡，然后围绕基于组织的开发形成习惯 |
| .gitignore 配置 | ✅ 存储库排除生成的文件、用户特定设置和凭据；仅包括打算版本的源文件团队 |

**反模式**

| 何处查看 | 什么不好的样子 |
| --- | --- |
| 作为真相来源的组织   | ⚏ 开发直接在共享 Sandbox 中进行，元数据会作为事后考虑导出到版本控制；组织和版本控制存在差异，导致部署失败 |
| .gitignore 不足    | 存储库包含生成的文件、用户特定设置、大型二进制文件或凭据；臃肿存储库和安全风险 |
| 模糊提交消息    | ⚠ 像“修复错误”或“更新”这样的提交没有提供发生了什么变化或为什么变化的上下文；阻碍了审计调查和未来的维护 |
| 大量不频繁提交 | 开发人员每周提交大型更改集，而不是每天多次提交小型增量；难以审查，难以隔离失败 |
| 直接提交到主要  | 开发人员绕过审查和验证，将更改直接推送到主/生产分支；消除了质量门槛 |
| 无分支策略    | 团队缺少一致的分支模型；开发人员创建任意分支名称和合并模式；造成混乱和合并冲突 |
| Git 中的二进制文件      | ⚏ 大型二进制文件（PDF、视频、归档）致力于 Git 膨胀存储库大小和减慢复制操作 |
| 提交凭据   | 提交到版本控制的 API 密钥、密码、集成凭据或安全令牌；即使从以后的提交中移除，也会造成安全漏洞 |
| 忽略合并冲突 | ⚏ 通过接受一方而不分析来解决合并冲突；丢失更改或引入错误 |
| 无提交验证   | ⚠ 团队从不验证提交的元数据是否真正代表预期的更改；元数据格式错误或意外更改会遗漏 |

## Sandbox 策略

**模式**

| 何处查看 | 好样的 |
| --- | --- |
| Developer Sandbox                | ✅ 单个开发人员使用 Developer Sandbox 进行功能工作、单元测试和快速迭代；每个开发人员都有专门的环境 |
| Developer Pro Sandbox            | ✅ 开发受管软件包或需要更高存储限制的团队使用 Developer Pro Sandbox 进行协同工作 |
| 部分复制 Sandbox             | ✅ 集成测试使用部分复制 Sandbox，其中包含通过数据模板配置的代表性数据示例（每个对象 10,000 条记录） |
| 完全复制 Sandbox                | ✅ 性能测试、类似生产的暂存和数据迁移验证使用包含完整生产数据和配置的完全复制 Sandbox |
| 数据灵敏性控制          | ✅ 完全复制 Sandbox 访问权限仅限于需要生产数据的角色；Shield Platform Encryption 数据掩码在适当时适用于非生产使用 |
| 集成端点配置 | ✅ 每个 Sandbox 层连接到相应的测试端点进行外部集成；生产集成从不从 Sandbox 连接 |
| 特定于环境的配置        | ✅ 集成架构使用自定义元数据类型或自定义设置来外部化每个环境的端点 URL、凭据和功能标志 |
| 刷新后自动化            | ✅ Sandbox 刷新会触发自动 Salesforce CLI 脚本，恢复特定于 Sandbox 的设置，包括集成凭据、测试数据种子、功能标记状态和电子邮件可送达性 |
| 刷新计划                 | ✅ Sandbox 刷新计划已记录并传达；计划在活动较少的时段进行刷新，以最大限度地减少团队中断 |
| 数据模板                     | ✅ 部分复制 Sandbox 使用设计良好的数据模板，选择对象中的代表性数据，保持引用完整性 |
| 命名约定                 | ✅ Sandbox 遵循明确的命名约定，指示目的、所有者和刷新周期（例如，“dev- integration-q2”、“uat-release-2-4”）。 |

**反模式**

| 何处查看 | 什么不好的样子 |
| --- | --- |
| 共享开发 Sandbox           | ⚠ 所有开发人员在单个共享 Sandbox 中工作，覆盖彼此的更改；对什么是可部署状态产生混淆 |
| 过时 Sandbox                      | ⚏ Sandbox 几个月没有刷新，与生产配置相差很大；在不具代表性的环境中测试会导致部署失败 |
| 完全复制中没有数据治理      | 完整复制 Sandbox，包含整个开发团队可以访问的生产 PII、财务数据、HIPAA 数据，无需访问控制或数据屏蔽 |
| Sandbox 中的生产集成 | Sandbox 直接连接到生产集成端点，从而产生影响生产数据或外部系统的测试事务的风险 |
| 手动刷新后配置    | ⚏ Sandbox 刷新需要几个小时的手动重新配置恢复设置；开销阻碍了根据需要频繁刷新 Sandbox |
| 无 Sandbox 文档             | 团队缺少有关 Sandbox 目的、刷新计划、数据内容或访问程序的文档；开发人员猜测哪个环境用于什么目的 |
| 单一环境类型              | ⚏ 团队出于所有目的仅使用一种 Sandbox 类型（通常是开发人员或完全复制）；错失了每个活动的适当 Sandbox 策略的好处 |
| Sandbox 囤积                     | 分配给个人或项目的 Sandbox，在不再需要时从未发布；尽管有可用的许可证，但人为稀缺 |
| 测试数据不足                 | ⚏ Sandbox 中的测试数据不代表生产数据特征（数量、关系、边缘个案）；在不现实的环境中测试会遗漏生产问题 |

## CI/CD 漏斗

**模式**

| 何处查看 | 好样的 |
| --- | --- |
| 源提交阶段         | ✅ 开发人员向 Git 中的功能分支提交更改，并带有解释上下文和理由的明确提交消息 |
| 静态分析阶段       | ✅ Salesforce 代码分析器扫描 Apex 的安全漏洞（OWASP 前 10 名）、性能反模式（循环中的 SOQL、循环中的 DML）、代码质量问题（复杂性、重复）和调控器限制风险；运行时间以秒为单位，提供即时反馈 |
| 单元测试阶段             | ✅ Apex 测试在短暂的临时组织或专用集成 Sandbox 中执行验证业务逻辑和调控器限制合规性；正确隔离的测试在不到 5 分钟内完成 |
| 验证部署阶段 | ✅ 元数据使用 Salesforce CLI 部署到集成 Sandbox，带有 - - checkonly 标志，用于仅验证部署运行测试，无需提交更改 |
| 集成测试阶段      | ✅ 自动化测试针对具有测试数据管理的共享集成环境，验证多组件工作流、外部集成合同、平台事件流和异步处理链 |
| 安全扫描阶段     | ✅ 其他安全工具扫描硬编码凭据、易受攻击的依赖关系、CRUD/FLS 违反和合规策略违反；重要发现会破坏构建 |
| UAT 部署阶段        | ✅ 变更通过所有自动网关部署到用户验收测试环境进行业务验证；部署可能是自动的，或者需要根据变更风险手动批准 |
| 生产部署阶段 | ✅ UAT 批准后，更改会部署到生产环境，具有自动一键执行、全面日志记录和即时回滚功能 |
| 漏斗执行时间     | ✅ 对于典型的更改，端到端漏斗可在 15 分钟内完成，支持快速反馈；对于大型部署或广泛的测试套件，时间更长 |
| 构建工件             | ✅ 漏斗会保留部署软件包、测试结果、安全扫描报表和执行日志，以便合规和故障排除 |
| 漏斗工具            | ✅ 团队将 Salesforce DevOps Center 用于平台本地 CI/CD，或与外部平台集成（GitHub Actions、GitLab CI、Azure DevOps、CircleCI、Jenkins、Copado、Gearset、AutoRABIT） |
| 失败通知       | ✅ 漏斗故障触发通知提交作者和相关渠道，诊断上下文支持快速补救 |
| 分支保护           | ✅ 主要/生产分支受保护，需要在合并前通过 CI 检查和批准审查；阻止直接提交 |
| 环境促销       | ✅ 更改通过定义的升级路径（开发 → 集成 → UAT → 生产）进行，并在每个阶段进行验证 |

**反模式**

| 何处查看 | 什么不好的样子 |
| --- | --- |
| 手动部署          | ⚠ 通过更改集或 Salesforce CLI 命令手动部署的更改，步骤不一致；人为错误、缺少步骤、缺少审计跟踪 |
| 无静态分析          | 漏斗跳过 Salesforce 代码分析器或类似工具；安全漏洞、性能反模式、代码质量问题到达生产环境 |
| 测试不足        | 漏斗仅验证最低 75% 的覆盖率，无需运行集成测试或验证关键用户流；回归会通过 |
| 无安全扫描        | 漏斗从不扫描硬编码凭据、易受攻击的依赖关系或 CRUD/FLS 违规；在生产或安全审查中发现的安全问题 |
| 漏斗执行缓慢     | 端到端的漏斗需要 45-60 分钟以上，这不利于频繁提交，并减慢反馈循环；开发人员提交不太频繁，累积较大的更改 |
| 忽略的漏斗故障   | ⚏ 团队忽略或覆盖漏斗故障，以满足截止日期要求；质量大门成为舞台，而不是实际控制 |
| 无测试环境奇偶性  | CI/CD 在配置、限制或数据特征与生产不同的环境中进行验证；通过验证并不保证生产成功 |
| 缺少回滚功能 | 漏斗自动部署，但不提供自动回滚；从错误部署中恢复需要手动紧急程序 |
| 无部署日志          | 在没有全面日志记录的情况下执行的部署；故障排除或审计部署变得困难 |
| 全有或全无测试      | 漏斗会针对每个更改运行所有测试，无论更改内容如何；即使文档更新，也会运行 30 分钟的测试套件 |

## 安全部署实践

**模式**

| 何处查看 | 好样的 |
| --- | --- |
| 功能标记                       | ✅ 高风险更改部署，在自定义元数据类型或自定义设置配置后禁用功能；支持在生产中测试，无需用户暴露，逐步推广到细分，A/B 测试，并通过配置更改即时回滚 |
| 功能标记范围                  | ✅ 为影响关键业务流程、性能敏感操作或新集成模式的高风险更改保留的功能标记；并非每个功能都需要标记 |
| 金丝雀部署                  | ✅ 关键业务更改首先发布到小用户子集（通过权限集或用户属性筛选，5%-10%）；在扩展推出前，24-48 小时密集监控金丝雀队列，测量成功率、性能、错误率 |
| 部署窗口                  | ✅ 在低用量期间安排部署，由 Event Monitoring API 使用日志通知，显示实际流量模式；避免高峰使用、月底关闭、季度结束、主要业务事件 |
| 部署通信            | ✅ 利益相关者会收到部署窗口的提前通知，包括预期持续时间、受影响的功能和回滚决策时间表 |
| 回滚程序                 | ✅ 每种部署类型的回滚程序都有记录并经过测试；在需要时，团队可以在 30 分钟内执行回滚 |
| 回滚测试                    | ✅ 在重要部署之前，在非生产环境中验证回滚程序，确保存在恢复功能 |
| 部署验证               | ✅ 部署后烟雾测试在发布后立即验证关键用户流、集成端点和主要功能 |
| 变更协调                 | ✅ 当更改跨越多个系统或需要跨 Salesforce 和外部平台同步发布时，协调部署策略 |
| 部署期间的监控        | ✅ 在部署时段和部署后观察期间（24-48 小时）启用增强监控，以监控错误率峰值、性能下降或用户流故障 |
| 适用于集成的蓝绿色模式 | ✅ 面向 Salesforce 的外部服务使用蓝绿色部署来维护两个类似生产的环境，先部署到非活动状态，验证后交换流量 |

**反模式**

| 何处查看 | 什么不好的样子 |
| --- | --- |
| 大爆炸部署            | ⚏ 大型版本包含许多同时部署的功能、重构和更改，无需逐步推出；失败会立即影响所有用户 |
| 高峰时段部署           | ⚠ 计划在高峰工作时间（中午、月底、季度末）发布，此时使用率最高，问题对用户的影响最大化 |
| 无回滚计划                | ⚏ 在没有记录和测试的回滚程序的情况下进行部署；当出现问题时，团队会争先恐后地找出恢复方法 |
| 功能切换为事后 | ⚠ ⸏ 在出现问题时被动添加的功能标记，而不是主动为高风险更改设计；将回滚选项限制为完全部署撤销 |
| 无部署验证        | ⚠ 部署到生产的更改没有部署后的烟雾测试；团队假设部署成功并继续前进；用户几小时后发现问题 |
| 未测试的回滚程序    | ⚏ 回滚过程已记录，但未在非生产环境中测试；在实际事故中，过程失败或证明不足 |
| 并发多系统更改 | 无需同步或兼容性测试即可在 Salesforce 和部署的外部系统中协调更改；导致集成失败 |
| 无监控增强       | ⚏ 在部署时段内，部署过程不会增强监控；通过用户投诉而不是主动警报发现问题 |
| 周末部署             | ⚏ 当随叫随到的覆盖范围缩小和供应商支持可用性受到限制时，周五晚上或周末部署的主要版本 |

## 测试策略

**模式**

| 何处查看 | 好样的 |
| --- | --- |
| 单元测试覆盖率           | ✅ 有意义的测试覆盖率，验证业务规则、边缘个案、错误路径和调控器限制方法；显著超过 75% 的最低要求 |
| 单元测试质量            | ✅ 测试验证业务逻辑，而不是平台功能；编写良好的单元测试快速（毫秒）、隔离（无共享状态）和专注（每个测试验证一个行为） |
| 测试数据策略           | ✅ 测试对常见测试数据使用 @TestSetup 方法；尽可能避免测试中的 SOQL 查询；使用 Test.loadData() 加载静态资源 |
| 模拟外部依赖性   | ✅ 单元测试使用测试存根和依赖注入模拟外部标注，无需实际 HTTP 请求即可快速执行 |
| 集成测试            | ✅ 使用代表性测试数据，验证触发器、流、平台事件、批处理作业和在 Sandbox 中运行的外部标注之间的交互 |
| 集成测试可靠性 | ✅ 集成测试具有可重复性和确定性；通过同步机制（例如平台事件重放 ID 和批处理作业轮询）解决零星故障 |
| 端到端测试             | ✅ 自动浏览器测试（Selenium、Playwright、Provar）验证用户的完整旅程，以便在用户交互时通过 UI 实践系统的关键业务流 |
| E2E 测试重点               | ✅ E2E 测试侧重于价值最高的用户路径，因为执行速度变慢（每次测试的分钟数）以及 UI 更改带来的更高维护负担 |
| 负载测试                 | ✅ 使用 Salesforce 负载测试服务或第三方工具，在实际并发用户负载和数据量下验证性能；揭示调控器限制问题、锁定争用、性能下降 |
| 负载测试频率          | ✅ 加载测试在主发布之前运行，并定期（每季度）验证当前生产量的 3x-5x 的性能 |
| 测试金字塔                 | ✅ 平衡的测试分配:多个单元测试(几百分钟 ) , 更少的集成测试(几十分钟 ) , 更少的 E2E 测试(不到 20 分钟 ) ; 基础反馈快,顶部验证全面 |
| 测试隔离               | ✅ 测试不相互依赖；可以以任何顺序运行；每个测试都使系统处于干净状态，或使用 @TestSetup 获得一致的起点 |
| 消极测试用例          | ✅ 测试验证错误处理、验证规则实施、权限实施和不利条件下的正常降级 |
| 调节器限制测试       | ✅ 测试专门验证接近调控器限制的行为，包括 SOQL 查询限制、DML 限制、CPU 时间、堆大小 |
| 连续测试执行    | ✅ 通过 CI/CD 漏斗，每次提交时自动运行测试；测试失败会阻止部署到更高的环境 |

**反模式**

| 何处查看 | 什么不好的样子 |
| --- | --- |
| 测试覆盖范围           | ⚠ 仅为实现 75% 的最小覆盖率而编写的测试，不验证业务规则或边缘个案；不声明任何内容或测试琐碎代码路径的测试 |
| 测试平台功能 | 测试会验证 Salesforce 保存记录或 SOQL 查询是否有效，而不是验证业务逻辑；在平台保证上浪费精力 |
| 无模拟策略               | 单元测试对外部系统进行实际标注；测试速度缓慢，易受外部系统可用性的影响，并消耗 API 限制 |
| 零星测试失败         | 根据执行时间、数据状态或测试执行顺序，测试通过或不可预测的失败；团队学习忽略失败并重新运行，直到测试通过 |
| 无集成测试         | 仅存在单元测试；团队从未验证触发器、流、平台事件和批处理作业是否正常工作 |
| 仅手动 E2E 测试        | ⚏ 在每个版本前手动验证关键用户流；没有自动 E2E 测试；当手动测试错过场景时，在生产中发现回归 |
| 无负载测试                | ⚏ 性能从未在实际并发负载下验证；在生产中发现调控器限制问题、锁定争用或性能下降 |
| 测试数据依赖性         | 测试取决于组织中存在的特定记录或假设特定的用户配置；在 Sandbox 刷新或配置更改时中断 |
| 无消极测试用例         | 测试仅验证幸福路径场景；从不测试错误处理、验证实施或权限检查；未发现的失败模式 |
| 跳过的测试                  | 失败的测试被评论为 @isTest，并被跳过而不是修复；测试套件会随着时间的推移而退化，因为更多的测试被忽略 |

## 代码审查

**模式**

| 何处查看 | 好样的 |
| --- | --- |
| 审查范围                   | ✅ 所有生产绑定更改都通过合并前需要批准的拉取请求进行代码审查；包括 Apex、Aura、LWC、流、验证规则、权限集、共享规则 |
| 审查条件核对清单         | ✅ 明确核对清单，涵盖安全性（CRUD/FLS 实施、输入验证）、性能（批量化、SOQL 优化）、调控器限制合规性（处理模式、递归预防）、可维护性（命名、文档、复杂性）、测试覆盖率（有意义的测试、边缘个案）、架构一致性（设计模式、问题分离） |
| 审查大小限制                | ✅ 拉取请求保持在 400 行以下有意义的更改，允许彻底审查；大型功能分为较小的增量更改，可单独审查和独立部署 |
| 审查时间                     | ✅ 在一个工作日内完成的审核保持开发势头并提供快速反馈；延迟的审核会产生上下文切换开销 |
| 自动审查前检查       | ✅ 静态分析、单元测试和安全扫描在人工审核请求前自动运行；自动检查会捕获机械问题，因此审核人员会专注于设计和业务逻辑 |
| 分布式审查责任 | ✅ 代码审核责任分配到团队，防止瓶颈和共享 Knowledge；初级开发人员审核高级代码，并在审核期间解释自己的代码 |
| 审核评论质量           | ✅ 审核人员提供具体、可操作的反馈，并说明理由；区分所需的更改（阻止问题）和建议（改进效果好） |
| 审查文档              | ✅ 拉取请求描述解释了发生了什么变化、为什么变化、进行了什么测试，以及任何特殊的部署注意事项或回滚程序 |
| 声明性配置审查         | ✅ 流、验证规则和权限更改的审查严格程度与代码相同；配置是架构性的，值得仔细检查 |
| 对评论采取后续行动             | ✅ 合并前处理的所有审查意见；回答的问题、实施的更改或未采纳建议的理由 |

**反模式**

| 何处查看 | 什么不好的样子 |
| --- | --- |
| 无代码审核             | ⚠ 直接提交到生产分支的更改，无需任何同行审查；消除了主要缺陷检测机制 |
| 橡皮图章            | 审查者可在数秒内批准拉取请求，而无需实际检查更改；审查成为复选框合规性，而不是质量门 |
| 单一审查者瓶颈 | 只有一个高级开发人员被授权审查代码；造成瓶颈和单点故障；Knowledge 集中而不是分散 |
| 大量拉取请求      | ⚠ 拉取请求包含跨越多个功能的数千行更改；无法彻底检查导致表面检查 |
| 延迟审查            | 拉取请求在几天或几周内处于未审查状态；开发人员失去上下文并转移到其他工作；当开发人员切换了思维上下文时，审查评论到达 |
| 无审查条件         | ⚏ 团队缺乏评审人应检查内容的明确标准；评审人评审质量差异很大；一些评审人关注风格，另一些关注逻辑，没有全面的 |
| 无需测试即可查看     | 审查者仅根据代码检查批准更改，而无需提取分支和本地测试，或验证自动化测试合格 |
| 忽略的自动检查   | 审查者批准拉取请求，尽管静态分析、安全扫描或单元测试失败；自动化质量门的目的落空 |
| 敌对评论文化     | 审查变成了个人批评或竞争活动，而不是协作性的质量改进；不利于学习和心理安全 |
| 无声明性审查      | 在 Apex 代码接受检查时，流、验证规则、权限集和共享规则未经审查就部署；在声明性配置中产生质量差距 |
