【发布时间】:2011-12-04 04:14:21
【问题描述】:
【问题讨论】:
-
正如 Maxim Vexler 所指出的,这篇 Flickr 帖子是关于功能标志的早期规范文章之一,并详细解释了它们的使用和实现code.flickr.com/blog/2009/12/02/flipping-out
【问题讨论】:
“功能标志”(或Feature Toggle)是一种能够轻松打开/关闭应用程序功能(子部分)的能力:
我猜这里的例子是,如果你需要,例如,如果负载太高,减少数据库查询,控制来减少功能集是很方便的。
虽然有 heaps of other reasons 你会想要使用它——其中一个主要功能是启用 Continuous Delivery:将事物推入生产/上线,但在完成之前禁用/切换该功能。我们经常使用我们所谓的“开发 cookie”来向开发团队展示未完成的功能。通过这种方式,我们可以在我们“取消切换”(完成)它并对公众可见之前,在多个发布/部署中测试生产中部分完成的工作(哦,是的!有更好的集成吗?)。
这是一个简单的包,可以帮助您在 ASP.NET MVC 领域做到这一点:https://github.com/cottsak/DevCookie(完全披露:我是作者)
Fowler 还有一个much longer article than the one linked above with a lot more details。
This post (on Fowler's site also) explains the various types of toggle strategies。 DevCookie 支持基于主线/主干的策略,在文章中称为“Release Toggle”。
Adil's answer 强调有很多条款和理由说明您可能需要一些这种基础设施。请记住,您可能只需要其中一些东西。例如,我可能只想启用一个简单、敏捷的部署/交付工作流程,因此一个简单的基础架构就足够了。如果您随后选择要进行完整的#leanstartup A/B 实验、队列测试和受控推出之类的东西,您应该考虑使用分析工具(例如Heap)来促进这些数据驱动的开发方法一个独特的解决方案。完成上述所有操作的切换基础架构将导致臃肿和不必要的复杂性。
如果你做到了这一步,那么你可能想看看我的一些other thoughts on Mainline Development, feature toggling, and other silly ideas like TEST, QA, SIT, STAND, CROUCH。
【讨论】:
功能标志(也称为功能翻转或feature toggle)是一个开关,用于根据需要启用或禁用可能很昂贵的功能(例如,当网站受到意外流量的冲击时)。这将为您争取一点时间,直到您扩大规模或负载高峰消失。
【讨论】:
Feature Flag 是一种通过配置关闭应用程序的某些功能而无需部署新代码的技术。
功能标志在持续部署功能但不一定“发布”到生产环境中的 CI 方案中发挥关键作用。
更多信息在这里:
-- 编辑:
【讨论】:
我的理解是,功能标志通过决定哪些用户接收某些功能来帮助您控制功能。
例如,假设您只希望您的 Beta 用户看到一项新功能。您可以为 Beta 用户“切换”该功能,而您的其他用户将看不到它。
LDUser user = new LDUser("user@test.com");
boolean showFeature = ldClient.toggle("your.feature.key", user, false);
if (showFeature) {
// application code to show the feature
}
else {
// the code to run if the feature is off
}
我正在为一些前端 JS A/B 测试测试 LaunchDarkly's feature flags - 似乎运行良好。您也可以查看this site for feature toggles and feature flag libraries。
【讨论】:
功能标志、功能切换、实验和受控推出是一个简单而强大的想法的同义词:将代码部署与功能推出分开。简而言之,这是一种将您的功能提交到生产环境的能力,同时选择您的客户中的哪些人(如果有的话)可以看到该功能。
Facebook's Gatekeeper 部分推广了它们。 LinkedIn 的 LiX 是另一个很好的例子。
接受这个简单的想法为许多最佳实践奠定了基础,包括:
持续部署/交付 - 一天内将多个代码推送到生产环境。
Trunk/Mainline 开发 - 特性分支应该只为拉取请求创建,而不是为长期特性开发而创建。
没有更多的发布火车让事情陷入困境。
生产中的 QA/Perf 测试 - 真正的 QA 和性能测试是在具有生产流量的生产基础架构上进行的。不要浪费时间建立广泛的性能实验室和临时环境。
实验 - 了解新功能如何影响您的 KPI。
出现问题时避免修补程序或代码回滚 - 修补程序和代码回滚都会带来压力,需要很长时间,并且会导致不必要的问题。相反,请关闭该功能或将其降低。
其他人提到了开源库。 Split 是完整解决方案(如 Gatekeeper 和 LiX)的一个很好的例子。我为斯普利特工作。
【讨论】:
功能标志基本上使您能够打开和关闭功能,而无需对代码进行任何更改或发布新版本。 这是一个重要的解决方案,尤其是对于移动应用程序开发人员来说,因为他们无法控制用户将他们的应用程序更新到新版本。
有几家公司为移动应用程序开发人员提供这项服务。
【讨论】:
在我的公司,我们在 SaaS 应用程序中引入的每个新功能都使用功能标志。除了对性能的好处之外,它还允许我们逐步推出新功能——首先向高级用户引入新功能,从他们那里获得反馈并即兴发挥,然后才能将其推出给所有用户。
它还允许我们为个人用户定制产品 - 高级用户想要所有功能;简单的用户可能只想要基本的东西,可能会对所有强大的复杂功能感到困惑。它还允许我们的销售团队进行追加销售。
当然,正如其他人所指出的,如果我们发现某个功能导致性能下降,我们可以简单地关闭该功能(对所有客户端或导致问题的一个客户端)。
【讨论】:
这里有很多很好的答案,所有答案都在 Martin Fowler 帖子中普及的重要的基本定义:
它们是“[允许]团队在不更改代码的情况下修改系统行为”的代码片段。
所以我们历来认为它们由伪代码表示:
if(app_settings["beta-mode"] == "true")
showAwesomeNewGui();
else
sameOldSnoozeFeset();
这是一种完全准确的思考方式,Matt 和 Adil 都很好地扩展了它,为功能标志提供了各种战术用例。
但我想提供一个修订后的定义,以反映现实在六年内如何演变以及自 dotnetdev 提出原始问题以来发生的变化。我为 Rollout.io 工作,这是一个功能标志平台,所以我在这次演变中占据了前排座位。
简而言之,功能标志不再只是一种在应用程序中打开和关闭部分功能的方法。这就像通过说“它是描述和货币数量”来回答“什么是发票行项目”。没错,但它并没有从发票本身的更广泛的角度出发。
功能标志是现代软件中总体战略解决方案的战术部分。它们是您将代码中的重要决策逻辑推迟到运行时获得更多信息的方法。而且,也许最重要的是,它们不再孤立地出现,只需检查版本号是否大于 2.7;使用它们的组织通常会将它们作为全面的、系统范围的产品方法的一部分。
正如其他人所提到的,Facebook 和 LinkedIn 是这方面的先驱,但在 2018 年,很多组织都在这样做。他们将运行时的决策逻辑问题作为开发战略、运营战略(或 DevOps 战略,如果你愿意)和产品战略的一部分。以下是此类问题的示例。
要让应用程序将大量此类决策推迟到运行时,您不能以特别的方式将功能标志放入您的应用程序,否则您将陷入技术债务。如今,您需要制定一个全面的功能标志管理策略,其中包括几个不同的组件。
那么,到底什么是特征标志?
嗯,它们是更广泛战略的重要组成部分,让应用程序能够适应技术和市场需求。
【讨论】:
功能标志(或功能切换)允许您在应用程序上远程启用功能,而无需重新构建/重新部署应用程序。 这允许您将代码部署到生产环境,但在您准备好之前不会发布该功能。 您可以针对特定用户,因此您可以为您的 Beta 用户启用一项新功能进行测试。
在我们公司,我们以前使用过LaunchDarkly 和来自FeatureFlags.io 的其他建议。我们还尝试使用 Firebase's Remote config 来尝试完成这项工作,但我们发现它并不适合此目的。
我们最终开发了我们自己的版本,称为Bullet Train,我们已将其开源。它结合了功能标志/切换和远程配置。
【讨论】:
功能标志有多种用途。 总体思路是将控制权委托给某个远程仪表板或某种类型的后台,哪些用户可以看到哪些功能。
一旦在代码中标记了某个功能,您现在可以使用多种方法来确定哪个用户在您的应用程序中看到它: 1. 开/关 - 向所有用户或不向所有用户显示该功能。 2. 逐步发布 - 仅向一部分用户展示该功能,然后逐步向所有用户展示。 3. 定位 - 根据特定用户的属性或特征向特定用户展示该功能。
帮助控制功能标志(布尔值)和功能配置(字符串、数字等)的工具通常称为功能管理平台 有一个很棒的功能管理服务,叫做Configz.io
【讨论】:
从编码的角度来看,功能标志可以像 if 语句一样简单,它包裹着您正在编写的一段新代码。当if 语句的计算结果为真(功能标志打开)时,将执行新代码。
在交付软件的真实示例中,上述if 语句的评估结果会根据软件运行的环境而有所不同。例如,如果应用程序正在您的 QA 服务器上执行,则功能标志将返回 true并且将看到新功能。如果它在您的生产服务器上执行,则功能标志将返回 false 并且该功能将被隐藏。
根据我在职业生涯中的个人经验,我通过以下方式使用功能标志:
将代码部署与向客户发布功能分离。这是我在开发过程中首次使用功能标志。我们用它来消除我们的营销和产品团队与进行开发和发布的工程团队之间的依赖关系。功能标志允许我们在发布前几周部署代码,而之前我们是在发布前一天晚上部署代码!
在生产中测试。在我们发布代码时使用功能标志之前,这是一个全有或全无的事件,我们的所有客户都获得了该功能,或者他们都没有。我们使用功能标志来允许我们一次向一小部分用户推出新功能。这使我们能够收集有关新功能的宝贵反馈和数据,而不会给整个客户群带来任何潜在问题的风险。
在开发生命周期中启用/禁用每个环境的功能。 我们在开发中广泛使用此功能,以实现更顺畅的部署过程 - 我们有一个 CI/CD 管道,其中功能标志的使用至关重要。
创建终止开关。我们已使用功能标志包装了应用程序的某些功能,允许我们在遇到任何问题时“终止”该功能当时的申请。例如,如果我们发现自己负载过重,我们可以关闭网站的某些非必要功能来帮助解决问题。
您可以在此处阅读更多about feature flags。
您可以通过多种方式将功能标志添加到您的代码中。
编写自己的库一开始似乎是个好主意,通常可以这样开始。但是,当您想要实现功能标志的更高级用例(例如向一定比例的用户推出或针对特定用户组)时,您很快就会遇到问题。创建自己的功能标志实现的另一个问题是,如果您使用多种语言,则需要多次实现代码。
使用功能标志的最佳和最简单的方法是使用在线功能标志管理服务,例如Floodgate。通过这种方式,您可以利用平台来完成所有繁重的工作,从而让您专注于为您的应用程序创建功能。
以下是如何使用 .NET SDK 将 Floodgate 功能标志添加到应用程序的示例。
using FloodGate.SDK;
var floodgateClient = new FloodGateClient("API-KEY");
var flag = floodgateClient.GetValue("a-new-feature", false);
if (flag)
{
// Execute the code for my new feature here...
}
如果您在开发团队中工作并且没有使用功能标志,并且您在团队内的部署和代码管理中遇到问题。使用功能标志可能是解决这些问题的好方法。特性标志还有一个很好的副作用,可以加快团队的开发速度。
Martin Fowler 对功能标志 here 进行了非常深入的描述,我建议您阅读。
【讨论】: