转载

再谈特性切换

据ThoughtWorks顾问Pete Hodgson介绍,按照使用时长和动态性进行分类,并以此为基础 实现恰当的特性切换 ,有助于应对运维复杂性。他在博文中扩展了 Martin Fowler的特性切换模式 ,并提出了发布、ops、试验和权限四类特性切换实现策略。在大型项目中,持续交付的困难需要特性切换来克服。

Pete写道,“特性切换是一项功能强大的技术,允许团队修改系统行为,而无需改变代码”。他提供了一个动态特性切换的简单示例:

function reticulateSplines() {   if( featureIsEnabled("use-new-SR-algorithm") ) {     return enhancedSplineReticulation();   } else {     return oldFashionedSplineReticulation();   } } 

在上面的例子中, featureIsEnabled() 方法调用的位置就是Pete所说的决策点或 切换点 ,该方法实现了一个简单的 切换路由 ,通常是基于一个简单的配置文件( 切换配置 )来实现。高级特性切换可能会考虑 切换上下文 ,并实现“用户群(将用户分组,一项特性对有的组总是开启,对有的组总是关闭)的概念”。

再谈特性切换

图片来源: http://martinfowler.com/articles/feature-toggles.html

作者提出了以下几种不同的切换类型:

  • 发布类切换 将部署从发布功能中分离出来,是暂时性的。它们常常用于 金丝雀发布策略 。“产品经理也可能会使用这个方法——不过是一个以产品为中心的变体——防止只完成了一半的产品特性暴露给终端用户。”它们可以用作特性分支的替代方案,在后一种情况下,太晚将分支特性合并到发布版本已被证实是一项复杂的任务。
  • Ops类切换 是对源于 Netflix Hystrix实现 的 断路器模式 的一种推广。这类切换会在运维层面修改系统,可以用于在高负载情况下优雅地停用某项服务。
  • 试验类切换 是短期切换,可以用于市场营销目的的A/B测试。在这种情况下,“系统的每个用户都被归入一个用户群,在运行时,切换路由会根据用户所在的群始终如一地将特定用户导向一个或另一个代码路径。”通过评估不同用户群的群体行为可以评价特性的效果。
  • 权限类切换 主要是长期的可选特性开关,可以用于实现定价策略,比如一个 付费模型 ,针对白银、黄金或铂金产品层级。这类切换需要一种比简单的if/then/else语句更健壮的实现以提高可维护性。

下面基于使用时长和动态性两个维度绘制的切换分类图:

再谈特性切换

图片来源: http://martinfowler.com/articles/feature-toggles.html

此外, Martin Fowler 将特性切换分为构建时切换和运行时切换。构建时切换可以作为运行时发布类切换的一种 静态替代方案 ,借此,哪一项特性进入发布是在编译期间决定的。在 各种Agile Release Trains 中,发布构建遵循一个固定的时间表。测试过的特性可以进入发布序列,而未完成或不稳定的特性在构建时会被排除在外。金丝雀微服务部署是另一种可以实现分离的可选方法。

Pete认为,“随着时间的推移,特性切换有一种越来越普及的趋势”。他提出了以下几项特性切换实现原则:

  • 运用 策略模式 , 避免切换点条件语句 ,而将if/then/else语句封装到路由层。
  • 引入实现决策逻辑的决策对象, 将决策点从决策逻辑中分离出来 。这样,举例来说,特性分组变化不会破坏代码。
  • 把决策对象作为构造函数参数注入, 将代码从特性切换基础结构中分离出来 ,以便可以用它切换任何想要切换的方法。这样,代码设计就可以不考虑切换路由,简化了开发测试。

Pete继续讨论了不同的切换配置选项。虽然有些发布类切换可以在应用程序启动时启用或禁用,但其他切换需要在运行时重新进行配置,比如ops类切换,同时,试验类切换和权限类切换则在每个用户会话甚或每次请求时发挥作用。作者建议使用静态配置作为特性切换配置的首选模式,因为一旦配置作为代码正确完成,就可以对它进行版本控制,并将其视为代码(审查、部署等等)。对于高级设置,他建议使用诸如Consul、etcd或Zookeeper这样的分布式键-值存储。

特性切换在大型项目持续交付管道中变得越来越重要,因为它们有助于 将部署从发布中分离出来 。协调分支合并以及并行向公共环境发布特性使团队必须序列化任务,导致速度下降。通过消除全是或全否的发布策略,特性切换帮助恢复了团队所需要的速度,虽然这是有成本的。除了会增加运维复杂度外,特性切换还会广泛引入其他的风险,尤其是使用发布类切换屏蔽未完成的代码时。 据Jim Bird介绍 ,特性切换会导致“代码更脆弱、更难测试、更难理解和维护、更难提供技术支持,而且更不安全。”他的主要论据是,将未经测试的代码引入生产环境是一个糟糕的主意,它们可能会在无意间暴露出来。 他举了一家金融机构因为这种情况破产的案例 。“特性切换需要一个鲁棒的工程过程、可靠的技术设计和成熟的特性切换生命周期管理。不具备这三个关键的条件,使用特性切换就是反生产力的。”

风险暂且搁置,Facebook在 最近的一篇论文 中探讨了特性切换在Web规模下的应用。Facebook的实现严重依赖特性切换。他们使用的不是基于配置的切换,而是基于规则的切换。一款名为Gatekeeper的UI管理工具用于激活特性,它运用一种灵活的选择过滤方法划分用户群。那样,特性就可以暴露给根据人口统计学和其他参数选出的用户:“起初,Gatekeeper可以只对开发这个特性的工程师开放该产品特性。然后,Gatekeeper可以向更大比例的Facebook员工开发该特性,比如从1%到10%再到100%。在内部测试成功后,它可以向某个特定区域内5%的用户开放。最后,该特性可以逐步在全球推出,比如,覆盖范围从1%到10%再到100%。”,论文作者这样解释道。

再谈特性切换

图片来源: http://abhishek-tiwari.com/post/decoupling-deployment-and-release-feature-toggles

Pete的博文是分期发布的,后续还会发布更多内容。

查看英文原文: Feature Toggles Revisited

原文  http://www.infoq.com/cn/news/2016/02/featuretoggles
正文到此结束
Loading...