← 返回首页
🚀

Feature Flag:灰度发布与A/B测试架构

📂 architecture ⏱ 2 min 323 words

Feature Flag:灰度发布与A/B测试架构

Feature Flag核心概念

Feature Flag(功能开关)是控制功能启用/禁用的运行时配置,支持灰度发布、A/B测试、紧急关闭等功能。将部署与发布解耦,实现按需发布。

Feature Flag生命周期:
开发 → 部署 → 灰度 → 全量 → 清理
  │      │      │      │      │
  └ Flag └ Flag └ Flag └ Flag └ 移除代码
        OFF    10%    100%   代码清理

Flag架构设计

Flag类型

// Feature Flag定义
interface FeatureFlag {
  key: string;              // 唯一标识
  name: string;             // 显示名称
  description: string;      // 描述
  type: 'boolean' | 'string' | 'number' | 'json';
  enabled: boolean;         // 全局开关
  rules: FlagRule[];        // 灰度规则
  fallback: any;            // 默认值
}

interface FlagRule {
  conditions: Condition[];  // 匹配条件
  percentage?: number;      // 流量百分比
  value: any;               // 返回值
}

interface Condition {
  attribute: string;        // 用户属性
  operator: 'eq' | 'neq' | 'in' | 'gt' | 'lt';
  values: string[];
}

Flag评估引擎

class FeatureFlagService {
  private flags: Map<string, FeatureFlag>;
  private cache: FlagCache;
  
  async evaluate(flagKey: string, context: UserContext): Promise<any> {
    // 1. 检查缓存
    const cached = await this.cache.get(flagKey, context.userId);
    if (cached !== undefined) return cached;
    
    // 2. 获取Flag配置
    const flag = this.flags.get(flagKey);
    if (!flag || !flag.enabled) return flag?.fallback;
    
    // 3. 评估规则
    for (const rule of flag.rules) {
      if (this.matchConditions(rule.conditions, context)) {
        // 4. 百分比灰度
        if (rule.percentage !== undefined) {
          const bucket = this.hashToBucket(context.userId, flagKey);
          if (bucket > rule.percentage) continue;
        }
        return rule.value;
      }
    }
    
    return flag.fallback;
  }
  
  private hashToBucket(userId: string, flagKey: string): number {
    const hash = crypto.createHash('md5')
      .update(`${userId}:${flagKey}`)
      .digest('hex');
    return parseInt(hash.substring(0, 8), 16) % 100;
  }
}

A/B测试集成

// A/B测试实验配置
interface ABTestExperiment {
  id: string;
  name: string;
  hypothesis: string;
  variants: Variant[];
  targetMetric: string;
  minSampleSize: number;
  confidenceLevel: number;  // 通常0.95
}

// 实验分配与追踪
class ABTestService {
  async assignVariant(experimentId: string, userId: string): Promise<Variant> {
    const experiment = await this.getExperiment(experimentId);
    const variant = this.hashToVariant(userId, experimentId, experiment.variants);
    
    // 记录分配事件
    await this.trackAssignment(experimentId, userId, variant.id);
    
    return variant;
  }
  
  async trackConversion(experimentId: string, userId: string, metric: string) {
    await this.analytics.track({
      experimentId,
      userId,
      metric,
      timestamp: Date.now()
    });
    
    // 检查是否达到统计显著性
    await this.checkSignificance(experimentId);
  }
}

Flag管理平台

# 后台管理界面功能
flag-management:
  features:
    - 创建/编辑/删除Flag
    - 规则可视化配置
    - 实时预览效果
    - 变更审批流程
  
  targeting:
    - 用户ID白名单
    - 用户属性匹配
    - 地域/设备/版本
    - 自定义属性
  
  rollout:
    - 渐进式灰度
    - 分时段发布
    - 定时启用/禁用
    - 紧急关闭按钮
  
  analytics:
    - Flag使用统计
    - A/B测试报告
    - 影响范围分析
    - 性能影响监控

最佳实践

  1. 命名规范:使用feature.xxx.yyy格式,如feature.checkout.new-payment
  2. 清理策略:全量发布后及时移除Flag代码,避免技术债
  3. 安全默认值:Flag异常时使用安全的默认值,不影响用户体验
  4. 审计日志:记录所有Flag变更,支持问题追溯