php 平滑加權輪循演算法實現
阿新 • • 發佈:2022-03-14
在做專案的過程中,特別是做abTest會用到輪循演算法,有順序輪循、平滑加權輪循:
廢話不多說上程式碼吧:
比較好理解。我用的是laravel框架實現的
1、簡單實現順序迴圈
//簡單輪巡 方法呼叫方 $arr = ['a', 'b']; $simple = new SimpleCyclic($arr); for ($i = 0; $i < 10; $i++) { $a = $simple->next(); echo $a; }
//SimpleCyclic.php 程式碼 具體實現類方法
<?php namespace App\common; use App\common\RobinInterface; //簡單輪巡 class SimpleCyclic { //輪巡陣列 protected $params; protected $total;//輪巡數量 //初始化當前指標所在位置 protected $currentPosition = -1; /** * SimpleCyclic constructor. * @param array $params 輪巡陣列 */ public function__construct(array $services) { $this->params = $services; $this->total = count($services); } public function next() { // 已排程完一圈,重置currentPos值為第一個例項位置 $this->currentPosition = ($this->currentPosition + 1) % $this->total; return $this->params[$this->currentPosition]; } }
2、實現平滑加權輪循
//平滑輪巡 //需要注意的是,在配置services服務列表時,同樣需要指定其權重: $services = [ '192.168.10.1:2202' => 5, '192.168.10.2:2202' => 1, '192.168.10.3:2202' => 1, ]; $smooth = new SmoothWeight($services); $a = $smooth->next(); echo "<pre>"; echo $a . "\n";
//SmoothWeight.php 實現類
<?php /** * 加權平滑輪巡 * Created by PhpStorm. */ namespace App\common; class SmoothWeight { private $services = []; private $currentPos = -1; public function __construct(array $services) { foreach ($services as $ip => $weight) { $this->services[] = [ 'ip' => $ip, 'weight' => $weight, 'current_weight' => $weight, ]; } } /** * 獲取指標 * @return mixed */ public function next() { // 獲取最大當前有效權重例項的位置 $this->currentPos = $this->getMaxCurrentWeightPos(); // 當前權重減去權重和 $currentWeight = $this->getCurrentWeight($this->currentPos) - $this->getSumWeight(); $this->setCurrentWeight($this->currentPos, $currentWeight); // 每個例項的當前有效權重加上配置權重 $this->recoverCurrentWeight(); return $this->services[$this->currentPos]['ip']; } /** * 獲取當前動態權重最大值 所在指標 也就是陣列得下標值 * @return int|string */ public function getMaxCurrentWeightPos() { $currentWeight = $pos = 0; foreach ($this->services as $index => $service) { if ($service['current_weight'] > $currentWeight) { $currentWeight = $service['current_weight']; $pos = $index; } } return $pos; } /** * 調整當前配置動態權重值 當前權重+配置權重值 */ public function recoverCurrentWeight() { foreach ($this->services as $index => &$service) { $service['current_weight'] += $service['weight']; } } /** * 獲取當前指標動態權重值 * @param $currentPos * @return mixed */ public function getCurrentWeight($currentPos) { return $this->services[$currentPos]['current_weight']; } /** * 設定當前指標動態權重值 * @param $currentPos * @param $currentWeight */ public function setCurrentWeight($currentPos, $currentWeight) { $this->services[$currentPos]['current_weight'] = $currentWeight; } /** * 獲取配置陣列權重數量總和 * @return int|mixed */ public function getSumWeight() { $num = 0; foreach ($this->services as $key => $value) { $num += $value['weight']; } return $num; } }
以上為實現的全部程式碼了,大家可以拷貝下來試試。