在实际的工作中,需要用到负载均衡的地方很多,当然在很多时候都是使用硬件负载均衡设备或者现成的负载均衡软件。虽是如此,做成程序员还是有必要了解一些具体的实现方式。
有时候在程序中可能需要根据配置访问一些地址,但是因为是在程序内部,有时候请求量不大或者没有必要“兴师动众”,因此自己实现一个负载均衡调度,一方面可以解决自己的实际问题,另一方面可以让自己对这类实现了解的更加深入。
下面是自己用php实现的一个加权负载均衡算法。具体时间就是比较简单了,我们根据权重生成访问地址的数量,然后随机取其中一个值。这种实现在请求量小的时候,实际的权重设定并不是非常准确,但是如果请求量较大的时候效果还是比较明显的。代码很简单:
function getRandomUrl($configs) {
$wConfigs = array();
foreach ($configs as $idx => $cfg) {
$weight = isset($cfg['weight']) ? intval($cfg['weight']) : 0;
if ($weight > 0) {
for ($i=0; $i<$weight; $i++) {
$wConfigs[] = $cfg['url'];
}
}
}
// get a random integer as the index of wConfigs
$idx = mt_rand(0, count($wConfigs) - 1);
return $wConfigs[$idx];
}
方法实现了,我们写个小程序测试下:
$configs = array(
array('url'=>'www.domain1.com', 'weight'=>2),
array('url'=>'www.domain2.com', 'weight'=>4),
array('url'=>'www.domain3.com', 'weight'=>1),
array('url'=>'www.domain4.com', 'weight'=>3),
);
// run and get stat result
echo 'Start running, please wait for a while...', PHP_EOL;
$num = 10000000;
$stat = array();
$timeUse = 0;
for ($i=0; $i<$num; $i++) {
$startTime = microtime(true);
$url = getRandomUrl($configs);
$endTime = microtime(true);
$timeUse += $endTime - $startTime;
if (!isset($stat[$url])) {
$stat[$url] = 0;
}
$stat[$url] += 1;
}
echo PHP_EOL;
// output result
echo str_repeat('-*-*', 10), PHP_EOL;
echo 'Stat Result:', PHP_EOL;
foreach ($stat as $url => $times) {
echo $url,"\t",$times,"\t",round(($times / $num * 100), 2),'%',PHP_EOL;
}
echo 'Average Time Cost: ', ($timeUse / $num),'s', PHP_EOL;
echo PHP_EOL;
Start running, please wait for a while...
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Stat Result:
www.domain2.com 3999278 39.99%
www.domain4.com 3000231 30%
www.domain1.com 2002104 20.02%
www.domain3.com 998387 9.98%
Average Time Cost: 5.3446655035019E-6s