Взвешенный алгоритм балансировки нагрузки в приложении PHP

Я хочу разрешить взвешенный адаптер с завода, который может быть настроен пользователем (включить / отключить и весовой%).

Пример:

  • AdapterW ≃ 20% транзакции
  • AdapterX ≃ 30% транзакции
  • AdapterY ≃ 40% транзакции
  • AdapterZ ≃ 10% от транзакции

Я могу допустить, что все предметы никогда не составят более ста (100%), но иногда любой адаптер может быть деактивирован.

У меня есть следующие параметры:

public function handleAdapter()
{
$isWActive = (boolean)$this->_config[self::W];
$isXActive = (boolean)$this->_config[self::X];
$isYActive = (boolean)$this->_config[self::Y];
$isZActive = (boolean)$this->_config[self::Z];
$WPercentage = (int)$this->_config[self::LOAD_BALANCE_W];
$XPercentage = (int)$this->_config[self::LOAD_BALANCE_X];
$YPercentage = (int)$this->_config[self::LOAD_BALANCE_Y];
$ZPercentage = (int)$this->_config[self::LOAD_BALANCE_Z];
.
.
.
return (self::W | self::X | self::Y | self::Z);
}

Как я могу сбалансировать взвешенный между этими адаптерами динамически?

редактировать

создал суть исполняемого кода: https://gist.github.com/markomafs/5d892d06d6670909f9b4

1

Решение

Возможно, это не лучший подход, но вы можете попробовать что-то вроде этого:

public function handleAdapter()
{
//an array to return the balanced entries
$balancedEntries[] = false;

//verifies which of the options are active
$isWActive = (boolean)$this->_config[self::W];
$isXActive = (boolean)$this->_config[self::X];
$isYActive = (boolean)$this->_config[self::Y];
$isZActive = (boolean)$this->_config[self::Z];

//get configured percentage of each
$WPercentage = (int)$this->_config[self::LOAD_BALANCE_W];
$XPercentage = (int)$this->_config[self::LOAD_BALANCE_X];
$YPercentage = (int)$this->_config[self::LOAD_BALANCE_Y];
$ZPercentage = (int)$this->_config[self::LOAD_BALANCE_Z];

//here you fill the array according to the proportion defined by the percentages
if ($isWActive) {
for ($i = 0; $i < $WPercentage; $i++) {
$balancedEntries[] = self::W;
}
}

if ($isXActive) {
for ($i = 0; $i < $XPercentage; $i++) {
$balancedEntries[] = self::X;
}
}

if ($isYActive) {
for ($i = 0; $i < $YPercentage; $i++) {
$balancedEntries[] = self::Y;
}
}

if ($isZActive) {
for ($i = 0; $i < $ZPercentage; $i++) {
$balancedEntries[] = self::Z;
}
}

return $balancedEntries;
}

И затем, в случае, если вы хотите пропорцию от 1 до 100 (как в процентах):

$balancedResult = $balancedEntries[array_rand($balancedEntries, 1)];

Так как array_rand вернет 1 ключ из исходного массива, вы используете его для получения его значения.

2

Другие решения

Еще одна попытка, это должно работать для вашего случая — но это работает, только если у вас есть адаптер в виде одной строки символов, это не видно по вашему вопросу.

public function handleAdapter()
{
# a map with all adapters
$map = array(
self::W => self::LOAD_BALANCE_W,
self::X => self::LOAD_BALANCE_X,
self::Y => self::LOAD_BALANCE_Y,
self::Z => self::LOAD_BALANCE_Z
);
# generate a string map with one char per percentage point
$stringMap = "";
foreach($map as $key => $value){
# skip if disabled
if(!$this->_config[$key]) continue;
# repeat the key for each percentage point
$stringMap .= str_repeat($key, (int)$this->_config[$value]);
}
# return a random string char from the map
return $stringMap[rand(0, strlen($stringMap) - 1)];
}
1

Изменить: я неправильно понял вопрос, ответ неверный.

Я понимаю ваш вопрос, так что вы всегда хотите вернуть адаптер с самой низкой нагрузкой, чтобы заставить трафик на этот адаптер.

public function handleAdapter()
{
$isWActive = (boolean)$this->_config[self::W];
$isXActive = (boolean)$this->_config[self::X];
$isYActive = (boolean)$this->_config[self::Y];
$isZActive = (boolean)$this->_config[self::Z];
$WPercentage = (int)$this->_config[self::LOAD_BALANCE_W];
$XPercentage = (int)$this->_config[self::LOAD_BALANCE_X];
$YPercentage = (int)$this->_config[self::LOAD_BALANCE_Y];
$ZPercentage = (int)$this->_config[self::LOAD_BALANCE_Z];

$map = array();
if($isWActive) $map[self::W] = $WPercentage;
if($isXActive) $map[self::X] = $XPercentage;
if($isYActive) $map[self::Y] = $YPercentage;
if($isZActive) $map[self::Z] = $ZPercentage;

asort($map);
return key($map);
}

Редактировать: Исправлено неправильно sort(), тебе нужно asort() поддерживать индекс.

0
По вопросам рекламы [email protected]