一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - PHP教程 - PHP實(shí)現(xiàn)負(fù)載均衡的加權(quán)輪詢方法分析

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

2019-09-10 11:52鹿呦呦 PHP教程

這篇文章主要介紹了PHP實(shí)現(xiàn)負(fù)載均衡的加權(quán)輪詢方法,簡單描述了常見的負(fù)載均衡算法,并結(jié)合實(shí)例形式分析了加權(quán)輪詢的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下

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

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

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

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

實(shí)現(xiàn)思路:

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

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

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

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

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

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

代碼:

<?php
// php實(shí)現(xiàn)負(fù)載均衡的加權(quán)輪詢(WRR)
class WRR {
  // 每次取100人
  const num = 100;
  // 上次取值時(shí)間,秒級(jí)時(shí)間戳
  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();
  // 用戶隊(duì)列
  public static $user_ids = array();
  public function __construct() {
    // 各機(jī)器的占比
    $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) { // 隊(duì)列超過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 { // 隊(duì)列不足100人
      $last_time = $this->last_time; // 上次訪問時(shí)間
      while (true) {
        $current_time = $this->getMillisecond();
        if (($current_time - $last_time) >= 10) { // 當(dāng)前時(shí)間和上一次取值時(shí)間超過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();  // 更新訪問時(shí)間
          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
    );
  }
  // 獲取毫秒級(jí)時(shí)間戳
  public function getMillisecond() {
    list($t1, $t2) = explode(" ", microtime());
    return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
  }
}
// 測(cè)試
$wrr = new WRR();
for ($i = 0; $i < 3; $i++) {// 模擬持續(xù)不斷的用戶請(qǐng)求
  $random = rand(10, 120);
  $user_ids = range(1, $random);
  WRR::$user_ids = $user_ids;
  $users = $wrr->getUsers();
  print_r($users);
}

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

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美专区在线观看 | 日本国产高清色www视频在线 | jizz女16处 | 欧美一区高清 | 四虎永久免费在线观看 | 欧美一区二区免费 | 天天做日日爱 | 色狠狠成人综合网 | 亚洲国产精品综合久久网络 | 色综合中文字幕在线亚洲 | 国产第一自拍 | 蝴蝶传媒免费安装 | 十大看黄网站 | 好男人免费高清在线观看2019 | 羞羞影院午夜男女爽爽影院网站 | 99视频在线看观免费 | 维修工的调教 | 好涨好大我快受不了了视频网 | 成人四虎 | 国产午夜亚洲精品不卡 | 无码天堂亚洲国产AV久久 | 日韩欧美中文字幕一区二区三区 | 国产精品久久一区 | 午夜秀场在线观看 | 日韩视频在线免费观看 | 亚洲欧美日韩综合在线播放 | 欧美一级一级做性视频 | 99 久久99久久精品免观看 | 国产精品久久久久久久牛牛 | 精品视频在线观看 | 日本艳鉧动漫1~6在线观看 | 精选国产AV精选一区二区三区 | 小女生RAPPER入口 | 日韩福利网 | xxxxxx日本处大片免费看 | 国产一二区视频 | 国语自产自拍秒拍在线视频 | 国产日韩欧美不卡www | 亚洲国产精久久久久久久 | 欧美伊香蕉久久综合类网站 | 丁香六月婷婷激情 |