零停机部署——特征开关(Feature Toggles)的应用

引言

在现代软件开发和部署中,零停机部署技术是实现高可用性和无缝用户体验的关键。本文将讨论功能开发开关(Feature Toggles)的类型并分析它们的优缺点,同时提供相关的例子和演示。

PS: https://github.com/WeiXiao-Hyy/blog整理了后端开发的知识网络,欢迎Star!

功能开发(Feature Toggles)

功能开关是一种在运行时控制软件功能是否可见或可用的技术。它允许开发团队随时启用或禁用特定功能,从而实现零停机部署。

常见示例

function reticulateSplines() {
  var useNewAlgorithm = false;
  // useNewAlgorithm = true; // UNCOMMENT IF YOU ARE WORKING ON THE NEW SR ALGORITHM

  if (useNewAlgorithm) {
    return enhancedSplineReticulation();
  } else {
    return oldFashionedSplineReticulation();
  }
}

function oldFashionedSplineReticulation() {
  // current implementation lives here
}

function enhancedSplineReticulation() {
  // TODO: implement better SR algorithm
}

功能开关的种类

Release Toggles

  • 用于为实践持续交付的团队启用基于主干的开发。允许将正在进行的功能潜入共享集成分支(例如master分支)。
  • 将[功能]发布与[代码]部署分离的持续交付原则的最常见方法。

Experiment Toggles

用于测试多个A/B实验时,将根据用户信息切换路由,将给定用户路由到一个代码路径或另一个代码路径中。通常用于电商的购买流程或号召性用语等内容进行数据驱动性的优化。

Ops Toggles

称为降级开关,当推出一项对性能影响不明确的新功能时,可能会引入Ops Toggle,以便系统操作员在生产环境中快速禁用或降级该功能。

大多数特征开发在新功能稳定之后,该标志就应该退役了。然而,系统拥有少量长寿命“特征开关”的情况并不常见,这些开关允许生产环境的操作员在系统承受异常高负载时可以优雅降级非重要的系统功能。

Permission Toggles

该开关和金丝雀发布有点类似,指的是新功能可以只发布给内部指定用户使用(内测)但是金丝雀发布是随机选择一小部分用户,而该开关是指定一小部分用户集合。

如何实现特征开关

解耦决策逻辑点

const features = fetchFeatureTogglesFromSomewhere();

function generateInvoiceEmail() {
  const baseEmail = buildEmailForInvoice(this.invoice);
  if (features.isEnabled("next-gen-ecomm")) {
    return addOrderCancellationContentToEmail(baseEmail);
  } else {
    return baseEmail;
  }
}

上述代码虽然看起来是一个合理的方法,但是却非常脆弱。

  • 引入魔法值next-gen-ecomm;
  • 为什么发票电子邮件需要知道订单取消内容是下一代功能集的一部分?
  • 随着功能的开发,这种“切换范围”的变化是很常见,如果只向某些用户推出订单取消功能怎么办?
// featureDecision.js
function createFeatureDecisions(features) {
  return {
    includeOrderCancellationInEmail() {
      return features.isEnabled("next-gen-ecomm");
    }
  // ... additional decision functions also live here ...
  };
}

// invoiceEmailer.js
const features = fetchFeatureTogglesFromSomewhere();
const featureDecisions = createFeatureDecisions(features);

function generateInvoiceEmail(){
  const baseEmail = buildEmailForInvoice(this.invoice);
  if( featureDecisions.includeOrderCancellationInEmail() ){
    return addOrderCancellationContentToEmail(baseEmail);
  }else{
    return baseEmail;
  }
}

将决策逻辑点和业务逻辑解耦,需要添加新的功能时只需要添加featureDecision中的方法,在invoiceEmailer中调用featureDecision中的方法。

避免(if/else)

如果Toggle Point是使用if语句来实现的。这对于简单,短暂的切换是有效的。但是,如果某个功能需要多个切换点。,或者希望切换点长期存在,则不建议使用if/else来实现。可以使用策略模式来优化代码中的if/else

如何使用特征开关

动态路由或动态配置

真正需要在系统运行时动态切换开关存在以下两种场景:

  1. Ops Toggles 需要降级某个板块;
  2. Permission Toggles和Experiment Toggles需要动态路由用户的请求;

前者通过在运行期间修改开关的值是动态的,而后者切换路由本质上是动态的。实际上仍然有相当多的静态的配置,也许只能通过重新部署来更改。

如果需要在生产环境中使用更加通用的切换控制机制,最好使用真正的分布式配置系统来构建,并及时清理过时的feature toggle。

参考文献

  • 30
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WeiXiao_Hyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值