濮阳杆衣贸易有限公司

主頁 > 知識庫 > PHP實現(xiàn)負(fù)載均衡的加權(quán)輪詢方法分析

PHP實現(xiàn)負(fù)載均衡的加權(quán)輪詢方法分析

熱門標(biāo)簽:宿州正規(guī)外呼系統(tǒng)軟件 萍鄉(xiāng)商鋪地圖標(biāo)注 合肥企業(yè)外呼系統(tǒng)線路 代理打電話機器人 電信外呼系統(tǒng)多少錢一個月 桂陽公司如何做地圖標(biāo)注 太原400電話申請流程 企業(yè)400電話辦理多少費用 神龍斗士電話機器人

本文實例講述了PHP實現(xiàn)負(fù)載均衡的加權(quán)輪詢方法。分享給大家供大家參考,具體如下:

1. 負(fù)載均衡算法有哪些?

  • 輪詢法:將請求按順序輪流地分配到后端服務(wù)器上,它均衡地對待后端的每一臺服務(wù)器,而不關(guān)心服務(wù)器實際的連接數(shù)和當(dāng)前的系統(tǒng)負(fù)載。
  • 隨機法:通過系統(tǒng)的隨機算法,根據(jù)后端服務(wù)器的列表大小值來隨機選取其中的一臺服務(wù)器進行訪問。
  • 源地址哈希法:根據(jù)獲取客戶端的IP地址,通過哈希函數(shù)計算得到一個數(shù)值,用該數(shù)值對服務(wù)器列表的大小進行取模運算,得到的結(jié)果便是客服端要訪問服務(wù)器的序號。采用源地址哈希法進行負(fù)載均衡,同一IP地址的客戶端,當(dāng)后端服務(wù)器列表不變時,它每次都會映射到同一臺后端服務(wù)器進行訪問。
  • 加權(quán)輪詢法:不同的后端服務(wù)器可能機器的配置和當(dāng)前系統(tǒng)的負(fù)載并不相同,因此它們的抗壓能力也不相同。給配置高、負(fù)載低的機器配置更高的權(quán)重,讓其處理更多的請;而配置低、負(fù)載高的機器,給其分配較低的權(quán)重,降低其系統(tǒng)負(fù)載,加權(quán)輪詢能很好地處理這一問題,并將請求順序且按照權(quán)重分配到后端。
  • 加權(quán)隨機法:與加權(quán)輪詢法一樣,加權(quán)隨機法也根據(jù)后端機器的配置,系統(tǒng)的負(fù)載分配不同的權(quán)重。不同的是,它是按照權(quán)重隨機請求后端服務(wù)器,而非順序。
  • 最小連接數(shù)法:由于后端服務(wù)器的配置不盡相同,對于請求的處理有快有慢,最小連接數(shù)法根據(jù)后端服務(wù)器當(dāng)前的連接情況,動態(tài)地選取其中當(dāng)前積壓連接數(shù)最少的一臺服務(wù)器來處理當(dāng)前的請求,盡可能地提高后端服務(wù)的利用效率,將負(fù)責(zé)合理地分流到每一臺服務(wù)器。

2.如何用PHP實現(xiàn)加權(quán)輪詢?

實現(xiàn)思路:

通過傳入不同的用戶id,然后給他們分配不同的主機。

首先,需要一個接收用戶id的數(shù)組。

其次,需要一個存主機的數(shù)組,這些主機有不同的權(quán)重。這里的權(quán)重可以這么考慮:

假設(shè)有abc三臺主機,權(quán)重分別為3,1,1,那么a的占比為0.6,b和c的占比各為0.2。

直接遍歷主機的數(shù)組,假如用戶來了100個人,到a的時候,a的占比是0.6,就從用戶數(shù)組里隨機取60個人分給a;輪到b時,b的占比是0.2,就從用戶數(shù)組里隨機取20人;同理,c20人,這樣就完成了100個請求的轉(zhuǎn)發(fā)。

可是真實場景不是固定一批用戶,而是持續(xù)不斷的用戶請求,由于轉(zhuǎn)發(fā)非???,當(dāng)來的新用戶非常少時,每次從用戶隊列中取完、轉(zhuǎn)發(fā)后立馬去用戶隊列中取,很有可能每次只取2條,造成請求全部給了a,b和c一直沒有的情況。這時候可以考慮按照不同策略從用戶隊列中取數(shù)據(jù)。假設(shè)以前5ms就處理完一次轉(zhuǎn)發(fā),則現(xiàn)在定義兩種策略,如果用戶隊列中有100個用戶時,就取出來,按著主機占比進行轉(zhuǎn)發(fā),如果用戶隊列中不足100人,但是當(dāng)前時間和上一次取值時間相差10ms,就取出來進行轉(zhuǎn)發(fā),這樣就可以累積5ms,而這5ms里隊列中又會多一些用戶請求,這樣就不會把所有請求都分給一臺機器了。

代碼:

?php
// php實現(xiàn)負(fù)載均衡的加權(quán)輪詢(WRR)
class WRR {
  // 每次取100人
  const num = 100;
  // 上次取值時間,秒級時間戳
  public $last_time;
  // 權(quán)重 machine=>weight
  public $machines = array(
    'a' => 3, // 0.6
    'b' => 1, // 0.2
    'c' => 1 // 0.2
  );
  // 占比
  public $proportion = array();
  // 用戶隊列
  public static $user_ids = array();
  public function __construct() {
    // 各機器的占比
    $total = 0;
    foreach ($this->machines as $machine => $weight) {
      $total += $weight;
    }
    $this->proportion['a'] = $this->machines['a'] / $total;
    $this->proportion['b'] = $this->machines['b'] / $total;
    $this->proportion['c'] = $this->machines['c'] / $total;
  }
  public function getUsers() {
    // 用戶人數(shù)
    $cnt = count(self::$user_ids);
    $a_num = 0;
    $b_num = 0;
    $c_num = 0;
    if ($cnt >= self::num) { // 隊列超過100人
      $a_num = round(self::num * $this->proportion['a']);
      $b_num = round(self::num * $this->proportion['b']);
      $c_num = $cnt - $a_num - $b_num;
    } else { // 隊列不足100人
      $last_time = $this->last_time; // 上次訪問時間
      while (true) {
        $current_time = $this->getMillisecond();
        if (($current_time - $last_time) >= 10) { // 當(dāng)前時間和上一次取值時間超過10ms
          $a_num = round($cnt * $this->proportion['a']);
          $b_num = round($cnt * $this->proportion['b']);
          $c_num = $cnt - $a_num - $b_num;
          $this->last_time = self::getMillisecond();  // 更新訪問時間
          break;
        }
      }
    }
    $a = array_splice(self::$user_ids, 0, $a_num);
    $b = array_splice(self::$user_ids, 0, $b_num);
    $c = array_splice(self::$user_ids, 0, $c_num);
    return array(
      'a' => $a,
      'b' => $b,
      'c' => $c
    );
  }
  // 獲取毫秒級時間戳
  public function getMillisecond() {
    list($t1, $t2) = explode(" ", microtime());
    return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
  }
}
// 測試
$wrr = new WRR();
for ($i = 0; $i  3; $i++) {// 模擬持續(xù)不斷的用戶請求
  $random = rand(10, 120);
  $user_ids = range(1, $random);
  WRR::$user_ids = $user_ids;
  $users = $wrr->getUsers();
  print_r($users);
}

真實的算法比這個復(fù)雜多了,它需要考慮一點,就是來過的用戶要保持原來分配的機器,除非原來的機器掛了。這樣做的原因是緩存。很多基于內(nèi)存的緩存,都是基于用戶級別的,所以相同的用戶保持同一臺機器,有助于提升性能。

更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《PHP數(shù)據(jù)結(jié)構(gòu)與算法教程》、《php程序設(shè)計算法總結(jié)》、《php字符串(string)用法總結(jié)》、《PHP數(shù)組(Array)操作技巧大全》、《PHP常用遍歷算法與技巧總結(jié)》及《PHP數(shù)學(xué)運算技巧總結(jié)》

希望本文所述對大家PHP程序設(shè)計有所幫助。

您可能感興趣的文章:
  • Nginx 安裝筆記(含PHP支持、虛擬主機、反向代理負(fù)載均衡)
  • PHP開發(fā)負(fù)載均衡指南
  • PHP實現(xiàn)負(fù)載均衡下的session共用功能
  • PHP實現(xiàn)負(fù)載均衡session共享redis緩存操作示例
  • Thinkphp結(jié)合AJAX長輪詢實現(xiàn)PC與APP推送詳解
  • PHP經(jīng)典算法集錦【經(jīng)典收藏】
  • php 分庫分表hash算法
  • php的hash算法介紹
  • PHP中對各種加密算法、Hash算法的速度測試對比代碼
  • PHP實現(xiàn)的一致性Hash算法詳解【分布式算法】

標(biāo)簽:白銀 廊坊 太原 衡陽 綏化 崇左 辛集 鄂州

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《PHP實現(xiàn)負(fù)載均衡的加權(quán)輪詢方法分析》,本文關(guān)鍵詞  PHP,實現(xiàn),負(fù)載,均衡,的,加權(quán),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《PHP實現(xiàn)負(fù)載均衡的加權(quán)輪詢方法分析》相關(guān)的同類信息!
  • 本頁收集關(guān)于PHP實現(xiàn)負(fù)載均衡的加權(quán)輪詢方法分析的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    安丘市| 泽州县| 古交市| 松桃| 西吉县| 济阳县| 寻乌县| 达州市| 湘潭县| 保康县| 揭东县| 塔城市| 麻城市| 江安县| 蓬安县| 辽阳市| 扎鲁特旗| 交城县| 栾城县| 沐川县| 策勒县| 凤庆县| 徐水县| 武冈市| 南雄市| 武汉市| 汕尾市| 黄骅市| 鞍山市| 湖北省| 苏尼特左旗| 尼玛县| 北宁市| 沙河市| 林口县| 定南县| 上虞市| 庆云县| 彰武县| 荔波县| 邳州市|