2015-11-18 4 views
1

Я хочу разрешить взвешенный адаптер с завода, который может быть настроен пользователем (включить/отключить и вес%).Алгоритм балансировки взвешенной нагрузки в 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

+0

Это поможет вам сделать вопрос, который получает эффективный ответ: http://stackoverflow.com/help/mcve –

+0

извините, но по этой ссылке, мой вопрос Minimal, полный и проверяемый. Можете ли вы мне помочь и отправить предложение по редактированию? – Markomafs

+0

Я только что проверил ссылку. В соответствии с этим, полным примером является один такой, который имеет «все части, необходимые для воспроизведения проблемы». MCE - это то, что я могу сделать. Я не могу запускать вашу функцию как есть. У него даже нет тегов . Когда я предоставляю ему теги и загружаю его, я получаю сообщение об ошибке «public» здесь. Чтобы запустить его, я должен исправить теги, создать свой объект, настроить код, который вызывает эту функцию, и распечатать результаты. Не знаю, как это сделать. Почему бы нам не сказать? –

ответ

2

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

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 ключ из исходного массива, вы используете его для получения его значения.

0

Редактировать: я неправильно понял вопрос, ответ неправильный.

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

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);  
} 

Edit: Исправлено неправильное sort(), вам нужно asort() для поддержания индекса.

+0

с asort, он будет реагировать только на более высокий процент Adapter. Желаю, например: AdapterY ≃ 40% транзакции, 40 из 100 запросов будут использовать этот адаптер, если вы поймете, что я имею в виду. – Markomafs

+0

В порядке, вы устанавливаете процент нагрузки вручную и хотите сбалансировать его на основе этого процента. Чем я полностью ошибаюсь в своем ответе :) –

+0

Признаюсь, вы ответили первым, что я пробовал. – Markomafs

1

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

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)]; 
} 
+0

В вашем решении, если имя адаптера имеет более 1 буквы, оно не будет работать – Markomafs

+0

@Markomafs, если уже упоминалось, что в ответе. –

+0

Извините! Адаптер может иметь более одной буквы! – Markomafs