PHP灰度发布与AB测试系统实现
PHP灰度发布与AB测试系统实现灰度发布和AB测试是产品迭代中的重要工具。它们可以在小范围内验证新功能的效果降低发布风险。今天说说PHP中的灰度发布和AB测试实现。灰度发布的核心是根据条件将流量分配到不同版本的服务上。条件可以是用户ID、IP、设备类型等。phpclass GrayRelease{private array $rules [];private array $versions [];public function addVersion(string $name, callable $handler, int $weight 0): void{$this-versions[$name] [handler $handler, weight $weight];}public function addRule(string $name, callable $matcher, string $version): void{$this-rules[] [name $name,matcher $matcher,version $version,];}public function getVersion(array $context): string{// 先检查规则foreach ($this-rules as $rule) {if (($rule[matcher])($context)) {echo 规则匹配: {$rule[name]} - {$rule[version]}\n;return $rule[version];}}// 加权随机$totalWeight array_sum(array_column($this-versions, weight));if ($totalWeight 0) {return array_key_first($this-versions);}$random rand(1, $totalWeight);$current 0;foreach ($this-versions as $name $config) {$current $config[weight];if ($random $current) {return $name;}}return array_key_first($this-versions);}public function execute(array $context): mixed{$version $this-getVersion($context);$handler $this-versions[$version][handler] ?? null;if ($handler null) {throw new RuntimeException(版本处理器不存在: {$version});}return $handler($context);}public function getStats(): array{return [versions array_map(fn($v) $v[weight], $this-versions),rules array_column($this-rules, name),];}}$gray new GrayRelease();$gray-addVersion(v1, function ($ctx) {return 旧版首页 (v1);}, 80);$gray-addVersion(v2, function ($ctx) {return 新版首页 (v2);}, 20);// 内部用户优先体验新版本$gray-addRule(内部用户, fn($ctx) ($ctx[user_type] ?? ) internal, v2);$gray-addRule(白名单用户, fn($ctx) in_array($ctx[user_id] ?? 0, [1001, 1002, 1003]), v2);$gray-addRule(Android用户, fn($ctx) ($ctx[platform] ?? ) android, v2);$users [[user_id 1001, user_type normal, platform web],[user_id 5001, user_type internal, platform ios],[user_id 9001, user_type normal, platform android],[user_id 7001, user_type normal, platform web],];foreach ($users as $user) {echo \n用户 {$user[user_id]} ({$user[user_type]}, {$user[platform]}):\n;echo . $gray-execute($user) . \n;}?AB测试系统可以更精细地控制实验phpclass ABTestExperiment{private string $name;private array $variants;private array $allocations [];private int $totalUsers 0;public function __construct(string $name, array $variants [control 50, treatment 50]){$this-name $name;$this-variants $variants;}public function assign(int $userId): string{$key abtest:{$this-name}:{$userId};$hash crc32($key);$totalWeight array_sum($this-variants);$bucket abs($hash) % $totalWeight;$current 0;foreach ($this-variants as $variant $weight) {$current $weight;if ($bucket $current) {$this-allocations[$variant] ($this-allocations[$variant] ?? 0) 1;$this-totalUsers;return $variant;}}return array_key_first($this-variants);}public function track(int $userId, string $event, array $data []): void{$variant $this-assign($userId);$log json_encode([time date(Y-m-d H:i:s),experiment $this-name,user_id $userId,variant $variant,event $event,data $data,]);file_put_contents(/tmp/abtest_{$this-name}.log, $log . \n, FILE_APPEND);}public function getResults(): array{$results [];foreach ($this-variants as $variant $weight) {$results[$variant] [weight $weight,users $this-allocations[$variant] ?? 0,percentage $this-totalUsers 0? round(($this-allocations[$variant] ?? 0) / $this-totalUsers * 100, 2) . %: 0%,];}return $results;}}// 首页改版AB测试$homepageTest new ABTestExperiment(homepage_redesign, [old 50,new 50,]);$users range(1, 10000);foreach ($users as $userId) {$variant $homepageTest-assign($userId);if ($variant new) {// 记录新版的点击率if (rand(0, 9) 3) {$homepageTest-track($userId, click);}}}echo AB测试结果:\n;print_r($homepageTest-getResults());?功能开关用于动态启用或禁用功能phpclass FeatureFlag{private Redis $redis;private string $prefix feature:;public function __construct(Redis $redis){$this-redis $redis;}public function enable(string $feature): void{$this-redis-set({$this-prefix}{$feature}, 1);$this-redis-publish(feature_changes, json_encode([feature $feature,action enable,time time(),]));}public function disable(string $feature): void{$this-redis-set({$this-prefix}{$feature}, 0);$this-redis-publish(feature_changes, json_encode([feature $feature,action disable,time time(),]));}public function isEnabled(string $feature): bool{return (bool)$this-redis-get({$this-prefix}{$feature});}public function isEnabledFor(string $feature, int $userId, int $percentage 50): bool{if (!$this-isEnabled($feature)) return false;$hash crc32({$feature}:{$userId});return abs($hash) % 100 $percentage;}}?灰度发布和AB测试是产品迭代的安全网。它们让新功能可以逐步上线出现问题可以快速回滚。灰度发布控制流量分配AB测试验证功能效果功能开关实现动态控制。三个工具配合使用可以构建完整的发布管理体系。