您好,登錄后才能下訂單哦!
怎么在PHP中實現負載均衡的加權輪詢方法?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
1. 負載均衡算法有哪些?
輪詢法:將請求按順序輪流地分配到后端服務器上,它均衡地對待后端的每一臺服務器,而不關心服務器實際的連接數和當前的系統負載。
隨機法:通過系統的隨機算法,根據后端服務器的列表大小值來隨機選取其中的一臺服務器進行訪問。
源地址哈希法:根據獲取客戶端的IP地址,通過哈希函數計算得到一個數值,用該數值對服務器列表的大小進行取模運算,得到的結果便是客服端要訪問服務器的序號。采用源地址哈希法進行負載均衡,同一IP地址的客戶端,當后端服務器列表不變時,它每次都會映射到同一臺后端服務器進行訪問。
加權輪詢法:不同的后端服務器可能機器的配置和當前系統的負載并不相同,因此它們的抗壓能力也不相同。給配置高、負載低的機器配置更高的權重,讓其處理更多的請;而配置低、負載高的機器,給其分配較低的權重,降低其系統負載,加權輪詢能很好地處理這一問題,并將請求順序且按照權重分配到后端。
加權隨機法:與加權輪詢法一樣,加權隨機法也根據后端機器的配置,系統的負載分配不同的權重。不同的是,它是按照權重隨機請求后端服務器,而非順序。
最小連接數法:由于后端服務器的配置不盡相同,對于請求的處理有快有慢,最小連接數法根據后端服務器當前的連接情況,動態地選取其中當前積壓連接數最少的一臺服務器來處理當前的請求,盡可能地提高后端服務的利用效率,將負責合理地分流到每一臺服務器。
2.如何用PHP實現加權輪詢?
實現思路:
通過傳入不同的用戶id,然后給他們分配不同的主機。
首先,需要一個接收用戶id的數組。
其次,需要一個存主機的數組,這些主機有不同的權重。這里的權重可以這么考慮:
假設有abc三臺主機,權重分別為3,1,1,那么a的占比為0.6,b和c的占比各為0.2。
直接遍歷主機的數組,假如用戶來了100個人,到a的時候,a的占比是0.6,就從用戶數組里隨機取60個人分給a;輪到b時,b的占比是0.2,就從用戶數組里隨機取20人;同理,c20人,這樣就完成了100個請求的轉發。
可是真實場景不是固定一批用戶,而是持續不斷的用戶請求,由于轉發非常快,當來的新用戶非常少時,每次從用戶隊列中取完、轉發后立馬去用戶隊列中取,很有可能每次只取2條,造成請求全部給了a,b和c一直沒有的情況。這時候可以考慮按照不同策略從用戶隊列中取數據。假設以前5ms就處理完一次轉發,則現在定義兩種策略,如果用戶隊列中有100個用戶時,就取出來,按著主機占比進行轉發,如果用戶隊列中不足100人,但是當前時間和上一次取值時間相差10ms,就取出來進行轉發,這樣就可以累積5ms,而這5ms里隊列中又會多一些用戶請求,這樣就不會把所有請求都分給一臺機器了。
代碼:
<?php // php實現負載均衡的加權輪詢(WRR) class WRR { // 每次取100人 const num = 100; // 上次取值時間,秒級時間戳 public $last_time; // 權重 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() { // 用戶人數 $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) { // 當前時間和上一次取值時間超過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++) {// 模擬持續不斷的用戶請求 $random = rand(10, 120); $user_ids = range(1, $random); WRR::$user_ids = $user_ids; $users = $wrr->getUsers(); print_r($users); }
php的框架:1、Laravel,Laravel是一款免費并且開源的PHP應用框架。2、Phalcon,Phalcon是運行速度最快的一個PHP框架。3、Symfony,Symfony是一款為Web項目準備的PHP框架。4、Yii,Yii是一款快速、安全和專業的PHP框架。5、CodeIgniter,CodeIgniter是一款非常敏捷的開源PHP框架。6、CakePHP,CakePHP是一款老牌的PHP框架。7.Kohana,Kohana是一款敏捷但是功能強大的PHP框架。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。