1

我想从工厂解决可由用户配置的加权适配器(启用/禁用和重量百分比)。

例子:

  • 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

4

3 回答 3

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 个键,因此您可以使用它来获取它的值。

于 2015-11-19T14:04:22.023 回答
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)];
}
于 2015-11-20T06:25:08.273 回答
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);    
}

编辑:修正了错误sort(),你需要asort()维护索引。

于 2015-11-19T14:19:09.310 回答