know more from here: https://www.youtube.com/watch?v=WMRjj06R6jg&list=UUkQX1tChV7Z7l1LFF4L9j_g

Feature flag: a way if exposing features to a sub-sent of your user base.

Release early, release often

Continuous integration is all about the entire team committing to master daily.

Small changes, shipped to production quickly, rather than living on feature branches, increase the velocity of new features and bug fixes reaching your customers.

But with most changes merged directly to master, how can you build new features with the confidence that shipping them won't have any impact on your customers, and only make it available once you're confident it's ready for prime time?

In a feature branch world, your new feature would be in the works for a while, changes are continuously merged in from master, making sure not to break anything.

But you won't know until it's finally merged and deployed to production whether your changes work.

How can you continuously ship new features to production with the confidence of not impacting your customers?

The answer is: feature flags.

A feature flag is a branching point that your code can utilize to determine whether or not a feature should be made available to one or more customers.

The original approach was made popular by the fine folks at Flickr. They needed a means to disable features when something is broken in production, to reduce the load on the database or on other parts of the system.

But feature flags can be used for much more than just disabling features in production.

  • Enable a feature only for a specific number of users, or even just for yourself to try it out in isolation.

  • Trial a new feature for a sample set of customers to compare how they're using it compared to the previous version of the feature.

    This allows you to run experiments with actual users before you put it live. You can collect feedback and iterate based on real production usage.

  • Enable it for your team to try out and give feedback on. At GitHub, this is known as staff mode. Next time you see a hubber in the wild, peek at their version of GitHub, I'm sure you'll notice some subtle differences.

  • Enable a feature for a specific set of users, or just your team for them to try it out before it's rolled out for everyone.

When a feature finally is rolled out for everyone, you can decide case by case on whether you want to leave a global feature flag so you can disable a new feature in the future.

The three use cases can even be put together. First you roll out a new feature for yourself, so you can try it out in production. Next you enable it for your team, and then you enable if for a subset of users. Finally, you make it available for everyone.

How do I implement feature flags?

At the core, feature flags are simple configuration settings with Boolean values.

if Travis::Application.config.features.repository_settings?
# code to handle settings
end

This example uses a Rails built-in means to manage application configuration, storing flags as simple true/false key value pairs.

For a Rails project, you can store this configuration in an initializer file.

# config/initializers/features.rb
Travis::Application.config.features = {
repository_settings: true
}

For every new feature, you can add the setting here, leaving all of them in one place to find, disable and enable them easily. All it takes is one change and a redeploy to enable or disable a feature.

This mechanism allows you to only fully disable or enable something, and only with redeploying the entire app, which can sometimes be burdensome. It also lacks the finesse to enable features for specific users or groups of users.

Flagging features at runtime

A more dynamic approach is to store the feature configuration in either an ephemeral or permanent storage, like Redis or your database, respectively.

Assuming your code continuously checks feature flags at runtime, all it takes is changing a value in the central configuration service and it can have an immediate affect on the running application without requiring a restart.

James Golick's rollout is a popular library to implement dynamic feature flags for Ruby applications. It allows you to enable features for specific users, groups of users, a percentage of users, or disable and enable them entirely. Hey, that library covers all of our bases!

Not coincidentally, it's the one we're using for Travis CI.

Rather than store the data in a configuration file, you can store them in Redis, or any supported key value store. Instead of asking the application's configuration, you ask rollout whether a feature is enabled.

if rollout.active?(:repository_settings, current_user)
# settings logic goes here
end

Enabling a feature for a user is just as simple.

rollout.activate_user(:repository_settings, User.find_by_login('roidrage'))

You can segment users into groups as well, based on the flags a specific users. Our friends at Librato use a mechanism similar to this for segmenting out users they'd like to test new features before they're available for everyone, the beta list if you will.

rollout.define_group(:beta_testers) do |user|
user.beta?
end

Document feature flags

When feature flags are collected using a centralized store like Redis, it gets harder to track which flags are available, what their defaults should be, and which features they affect.

Make sure to keep simple documentation around where you collect feature flags to make sure the right ones are changed at the right time.

Feature flags at Travis CI

We're using rollout for our feature flags, but we've added a few more things that we need. Some features on Travis CI are only made available for certain repositories or certain accounts and all of their respective repositories.

Most of our feature flags are built for production runtime though. We have means to enable build scheduling, for instance during a maintenance, without taking down the entire process. That way we can still process actively running builds without scheduling new ones.

We've used feature flips to migrate to different implementations of something too. Originally, our user synchronization went through RabbitMQ and was handled by the same process that handles scheduling builds.

As we switched over to a process based on Sidekiq, we enabled our own users first to make sure the process works, before we finally enabled it for everyone. We eventually moved the feature flip, as the code that originally handled this part was deleted as well.

We're also using them to enable custom subscription plans for some of our customers.

Ship with confidence

Feature flags are very handy to roll out new features gradually, but they also give you higher control over your system running in production as well.

New features, even in raw shape, can be put to use and test in the production environment as soon as something is ready for trying out, and without impacting users unless you choose to.

On top of that, they give you a means to disable certain features during a production incident.

Is your project using feature flags or a similar means? Feel free to share your experiences in the comments.

Feature Flag的更多相关文章

  1. 给你的 ASP.NET Core 程序插上 Feature Flag 的翅膀

    前言 我们知道,目前大多数应用程序在正式发布到生产环境之前都会经历多个不同的测试环境,通过让应用程序在多个不同的环境中运行来及时发现并解决问题,避免在线上发生不必要的损失.这是对于整个软件的发布流程来 ...

  2. Sentry 开发者贡献指南 - Feature Flag

    功能 flag 在 Sentry 的代码库中声明. 对于自托管用户,这些标志然后通过 sentry.conf.py 进行配置. 对于 Sentry 的 SaaS 部署,Flagr 用于在生产中配置标志 ...

  3. 基于Feature Flag的下一代开发模式

    渐进式发布(Progressive Delivery)被认为是持续发布(Continous Delivery)的下一代形态,其专注于增强发布过程控制与降低发布风险,最终提高整体收益.国际科技巨头比如A ...

  4. 微软Azure配置中心 App Configuration (二):Feature Flag 功能开关特性

    写在前面 Web服务开发过程中我们经常有这样的需求: 某些功能我必须我修改了配置才启用,比如新用户注册送券等: 某个功能需到特定的时间才启用,过后就失效,比如春节活动等: 某些功能,我想先对10%的用 ...

  5. 【亲述】Uber容错设计与多机房容灾方案 - 高可用架构系列

    此文是根据赵磊在[QCON高可用架构群]中的分享内容整理而成.转载请事先联系赵磊及相关编辑. 赵磊,Uber高级工程师,08年上海交通大学毕业,曾就职于微软,后加入Facebook主要负责Messen ...

  6. 使用Trello实现敏捷项目管理

    使用Trello实现敏捷项目管理 作者                     侯伯薇        发布于    五月 24, 2012     |     1         讨论 新浪微博腾讯微 ...

  7. 八卦某 G 的前端开发方式及流程

      他山之石,可以攻玉. 话说本人从毕业到现在一直在某 B 公司工作,前些年折腾过不少开发方式和工具,但总觉得或许有更好的方案,所以很好奇其它公司内部是如何工作的,我曾经浏览过某 Y 公司内部无所不包 ...

  8. Package org.xml.sax Description

    This package provides the core SAX APIs. Some SAX1 APIs are deprecated to encourage integration(集成:综 ...

  9. Linux 内核使用的 GNU C 扩展

    gcc核心扩展linuxforum(转)=========================== Linux 内核使用的 GNU C 扩展 =========================== GNC ...

随机推荐

  1. Android开发:碎片Fragment完全解析fragment_main.xml/activity_main.xml(转)

    注明:这个转的,见谅未能标明原始出处 我们都知道,Android上的界面展示都是通过Activity实现的,Activity实在是太常用了,我相信大家都已经非常熟悉了,这里就不再赘述. 但是Activ ...

  2. GNU Binutils工具

    参考<程序员的自我修养---连接.装载与库> 以下内容转贴自 http://www.cnblogs.com/xuxm2007/archive/2013/02/21/2920890.html ...

  3. SPA解释:单页应用程序

    单页Web应用(single page web application,SPA),就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序. 单页W ...

  4. Ubantu 安装 LAMP环境

    1.通过 apt-get update 命令从ubantu软件源中下载可安装软件的列表. 2.通过一条命令可以一次性的安装LAMP apt-get install apache2 php5 mysql ...

  5. zedboard启动过程分析

    1.经过几天的努力看懂了zedboard的部分启动过程 陆书与何宾老师的书上都说到了BootRom , 这个是被称为第0阶段启动引导,这阶段的代码在上电或者热复位时执行,启动代码不可更改,这是比我们所 ...

  6. js设计模式(4)---组合模式

    0.前言 今天是建党节,新疆那边又开始了闹腾.作为立志成为码农的我,现在已经从一个大愤青淡化为一个小愤青,对这些国家民生大事不在血气喷发,转而把经历发泄在技术问题上面,因而在扯一篇随笔吧,把无处发泄的 ...

  7. RxJava 平常使用

    本文转载自: http://blog.csdn.net/theone10211024/article/details/50435325 一.Scheduler线程切换 这种场景经常会在“后台线程取数据 ...

  8. 关于iOS6应用中第三方类库不支持armv7s的问题解决

    今天编译ios6+cocos2d v2 .1 beta2制作的游戏,出现下面的错误: ld: file is universal (3 slices) but does not contain a(n ...

  9. execute连接 类型

    set rs=server.createobject("adodb.recordset") sql="select top 10 id,name from tablena ...

  10. CLR via C# 计算限制的异步操作读书笔记

    1. 使用线程池搪行简单的计算限制操作 ThreadPool.QueueUserWorkItem(WaitCallback callback) 2.CLR默认情况下自动使初始线程的执行上下文流向辅助线 ...