采用功能标志的渐进式试验

随着 DevOps 团队转向专注于持续交付功能的敏捷方法论,控制用户如何使用这些功能的需求变得越来越重要。 功能标志是一个很好的解决方案,可以限制用户访问新功能,无论是用于营销目的还是用于生产测试

分离部署和曝光

使用功能标志,团队可以选择给定的一组功能在用户体验中是否可见和/或在功能中是否调用。 新功能可以作为普通开发过程的一部分进行构建和部署,而无需对这些功能进行广泛访问。 特性的部署很方便地与它们的公开分离。

标志为单个用户提供运行时控制

标志还提供细粒度控制,一直到单个用户。 当需要启用一个功能时,无论是针对一个用户、一个小组还是每个人,团队都可以简单地更改功能标志,以点亮功能,而无需重新部署。

专题标志的范围将根据专题的性质和受众而有所不同。 在某些情况下,功能标志会自动为每个人启用该功能。 在其他情况下,功能将在逐个用户的基础上启用。 如果用户愿意,团队还可以使用功能标志来允许他们选择启用某个功能。 功能标志的实现方式实际上没有限制。

支持早期反馈和实验

功能标志是支持早期实验的好方法。 有些功能在早期可能会有粗糙的边缘,这可能只有最早采用者才会感兴趣。 试图将那些尚未准备好的功能推向更广泛的受众可能会引起不满。 但是,从愿意处理正在进行的功能的用户那里收集反馈的好处是非常宝贵的。

快速关闭开关

有时候能够关掉某些项目是很有帮助的。 例如,假设一个新功能没有按预期工作,并且存在会在其他地方引发问题的副作用。 您可以使用功能标志快速关闭新功能,以便回滚到受信任的行为,而无需重新部署。 虽然功能标志通常被认为是用户界面功能,但它们也可以很容易地用于架构或基础结构的更改。

标准阶段

Microsoft 使用标准的推出过程来打开功能标志。 有两个独立的概念:用于部署,阶段用于功能标志。 了解更多关于环和阶段的信息。

阶段都是关于披露或曝光的。 例如,第一阶段可以是团队帐户和成员的个人帐户。 大多数用户不会看到任何新的东西,因为唯一打开标志的地方是第一阶段。 这使团队能够充分使用和试验它。 一旦团队签核,选定的客户就可以通过第二阶段的功能标志选择加入。

选择加入

允许用户在可行的情况下选择使用功能标志是一种很好的做法。 例如,团队可以公开与用户的偏好或设置相关联的预览面板。

Screenshot of opt-in preview pane.

将标志与遥测一起使用

功能标志提供了一种增量公开更新的方法。 然而,团队必须持续监视正确的指标,以衡量是否为更广泛的风险敞口做好了准备。 这些指标应该包括使用行为,以及更新对系统运行状况的影响。 重要的是要避免因为似乎没有发生什么坏事就认为一切都好的陷阱。

功能标志示例

请考虑下面的例子。 团队在这里添加了几个按钮,用于提取请求 UI 中的挑拣还原。 这些是使用功能标志部署的。

Screenshot of pull request UI example.

定义功能标志

曝光的第一个功能是还原按钮。 该解决方案使用 XML 文件来定义所有功能标志。 在这种情况下,每个服务有一个文件,这就产生了删除旧标志的动机,以防止该部分变长。 团队将删除旧标志,因为控制该文件的大小是一种自然的动机。

<?xml version="1.0" encoding="utf-8"?>
<!--
  In this group we should register Azure DevOps specific features and sets their states.
-->
<ServicingStepGroup name="AzureDevOpsFeatureAvailability" … >
  <Steps>
    <!-- Feature Availability -->
    <ServicingStep name="Register features" stepPerformer="FeatureAvailability" … >
      <StepData>
        <!--specifying owner to allow implicit removal of features -->
        <Features owner="AzureDevOps">
           <!-- Begin TFVC/Git -->
           <Feature name="SourceControl.Revert" description="Source control revert features" />

一个通用的服务器框架鼓励整个团队的重用和规模经济。 理想情况下,项目将有适当的基础结构,这样开发人员就可以简单地在中央存储中定义一个标志,并为他们处理其余的基础结构。

运行时检查功能标志

此处使用的功能标志名为 SourceControl.Revert。 以下是该页面中的实际 TypeScript,它说明了对功能可用性检查的调用。

private addRevertButton(): void {
 if (FeatureAvailability.isFeatureEnabled(Flags.SourceControlRevert)) {
     this._calloutButtons.unshift(
         <button onClick={ () => Dialogs.revertPullRequest(
             this.props.repositoryContext,
             this.props.pullRequest.pullRequestContract(),
             this.props.pullRequest.branchStatusContract().sourceBranchStatus,
             this.props.pullRequest.branchStatusContract().targetBranchStatus)
         }
         >
             {VCResources.PullRequest_Revert_Button}
         </button>
        );
     }
}

上面的例子说明了 TypeScript 中的用法,但使用 C# 也可以很容易地访问它。 代码检查该功能是否已启用,如果启用,则呈现一个按钮以提供该功能。 如果该标志未启用,则跳过该按钮。

控制功能标志

一个好的功能标志平台将提供多种方式来管理是否设置了给定的标志。 通常,存在通过 PowerShell 和 Web 界面控制标志的使用场景。 对于 PowerShell,真正需要公开的只是获取和设置功能标志状态的方法,以及特定用户帐户标识符等可选参数(如果适用)。

通过 Web UI 控制功能标志

以下示例使用团队为此产品公开的 Web UI。 请注意 SourceControl.Revert 的功能标志。 这里列出了两个个人帐户:halluxbuckh-westeur。 该状态已为恰好位于中北部的 hallux 设置,并为西欧的另一个帐户结算。

Screenshot of controlling feature flags through web UI.

功能标志的性质将决定功能的公开方式。 在某些情况下,曝光将遵循环形和阶段模型。 在其他情况下,用户可以通过配置 UI 进行选择,甚至可以通过向团队发送电子邮件进行访问。

功能标志的注意事项

一旦某个功能向所有人推出,大多数功能标志都可以失效。 此时,团队可以删除代码和配置中对标志的所有引用。 在每个冲刺的开头都包含一个功能标志评审是一个很好的做法。

同时,可能存在一组由于各种原因而持续存在的功能标志。 例如,团队可能希望在生产服务完全切换后的一段时间内保留一个功能标志,该标志用于分支某个基础结构。 但是,请记住,在未来明确清除功能标志期间,可能会重新激活此潜在的代码路径,因此需要对其进行测试和维护,直到删除该选项。

功能标志和分支策略

功能标志使开发团队能够在不影响其他人的情况下将不完整的特性包含在 main 中。 只要代码路径被隔离在功能标志后面,构建和发布该代码通常是安全的,不会产生影响正常使用的副作用。 但是,如果在某些情况下某个功能需要依赖项,例如在公开 REST 端点时,团队必须考虑这些依赖项如何在不公开该功能的情况下创建安全或维护工作。

降低风险的功能标志

有时,新功能有可能带来破坏性或破坏性的变化。 例如,产品可能正在经历从宽数据库模式到长数据库模式的转换。 在这种情况下,开发人员应该在很短的时间内创建一个功能分支。 然后,他们对分支进行破坏稳定的更改,并将该功能保留在标志后面。 一种流行的做法是,团队在没有造成任何伤害的情况下,尽快将更改合并到 main。 如果没有将未完成的功能隐藏在功能标志后面的能力,这是不可行的。

功能标志有助于在主要中工作

如果您遵循开发阶段讨论的常识性实践,那么在 main 中工作是缩短 Develop 周期的好方法。 当与功能标志相结合时,开发人员可以快速地向上游合并特性,并将它们推送至测试 Gauntlet。 质量代码可以快速发布,以便在生产中进行测试。 经过几次冲刺之后,开发人员将认识到功能标志的好处,并积极使用它们。

如何决定是否使用功能标志

对于给定的更改,功能团队拥有是否需要功能标志的决定权。 并不是每个更改都需要,所以当开发人员选择进行给定的更改时,需要自行判断。 在前面讨论的还原功能的情况下,使用功能标志来控制曝光是很重要的。 允许团队拥有关于其功能领域的关键决策是在有效的 DevOps 组织中实现自主性的一部分。

构建与购买

虽然可以构建自己的功能标志基础结构,但通常建议采用 LaunchDarklySplit 这样的平台。 最好投资于构建功能,而不是重新构建功能标志功能。

后续步骤

了解有关在 ASP.NET Core 应用程序中使用功能标志的详细信息。