詳解Nginx輪詢算法底層實現的方法_nginx

來源:腳本之家  責任編輯:小易  

請確定另外一個地址是否可以訪問,如果另外一個地址nginx訪問不了,那么就會出現你這種情況,永遠只訪問那個可以訪問的地址www.13333515.buzz防采集請勿采集本網。

輪詢算法簡介

從你的描述來看,用戶名和密碼的話,應該是用了session,在一個服務器上設置的session,在另外一個服務器上沒有起作用,如果想做負載均衡的話,這兩個tomcat服務器也需要設置。具體的方法查一下資料吧,這

在工作中很多人都使用到了nginx,對nginx得配置也是爛熟于心,今天我主要想介紹一下nginx輪詢算法得幾種底層實現方式。

第二層不需要做LB,通過第一層的時候已經實現了負載均衡,nginx可以一臺,可以2臺,2臺就是做冗余,防止一臺nginx當掉,2臺nginx的話,最好安裝keepalived實現冗余,可以做成雙活,通過dns實現兩

簡單輪詢算法

nginx有5種負載均衡的策略: 1、輪詢;2、權重;3、ip_hash;4、fair;5、url_hash。以上。

這種算法比較簡單,舉個例子就是你有三臺服務器

Nginx負載均衡一些基礎知識: nginx 的 upstream目前支持 4 種方式的分配 1)、輪詢(默認) 每個請求按時間順序逐一分配到不同的后端服務器,如果后端服務器down掉,能自動剔除。2)、weight 指定

第一臺服務器 192.168.1.1
第二臺服務器 192.168.1.2
第三臺服務器 192.168.1.3

}在使用proxy_pass指令把請求轉發給后端時:如果不指定負載均衡方式,nginx默認就是按照輪詢的方式進行請求轉發的。因此配置如下所示: (1)在upstream.conf文件中增加后端機器列表的配置: upstream test_

第一個請求過來之后默認訪問第一臺,第二個請求過來訪問第二臺,第三次請求過來訪問第三臺,第四次請求過來訪問第一臺,以此類推。以下是我代碼實現簡單得算法:

public class SimplePolling { /** * key是ip */ public static List <String> ipService = new LinkedList <>(); static { ipService.add("192.168.1.1"); ipService.add("192.168.1.2"); ipService.add("192.168.1.3"); } public static int pos = 0; public static String getIp(){ if(pos >= ipService.size()){ //防止索引越界 pos = 0; } String ip = ipService.get(pos); pos ++; return ip; } public static void main(String[] args) { for (int i = 0; i < 4; i++) { System.out.println(getIp()); } }}

模擬執行4次執行結果是

在這里插入圖片描述

此時如果我有一臺服務器性能比較好(比如192.168.1.1),我想讓這臺服務器處理多一點請求,此時就涉及到了權重得概率,這種算法就不能實現,請看我后面描述的輪詢升級版算法。

加權輪詢算法

此時我需要把我前面3臺服務器都設置權重,比如第一臺設置5,第二臺設置1,第三臺設置1

第一臺服務器 192.168.1.1 5
第二臺服務器 192.168.1.2 1
第三臺服務器 192.168.1.3 1

此時前5個請求都會訪問到第一臺服務器,第六個請求會訪問到第二臺服務器,第七個請求會訪問到第三臺服務器。

以下是我給出的代碼案例:

public class WeightPolling { /** * key是ip,value是權重 */ public static Map<String, Integer> ipService = new LinkedHashMap<>(); static { ipService.put("192.168.1.1", 5); ipService.put("192.168.1.2", 1); ipService.put("192.168.1.3", 1); } public static int requestId = 0; public static int getAndIncrement() { return requestId++; } public static String getIp(){ //獲取總的權重 int totalWeight =0; for (Integer value : ipService.values()) { totalWeight+= value; } //獲取當前輪詢的值 int andIncrement = getAndIncrement(); int pos = andIncrement% totalWeight; for (String ip : ipService.keySet()) { if(pos < ipService.get(ip)){ return ip; } pos -= ipService.get(ip); } return null; } public static void main(String[] args) { for (int i = 0; i < 7; i++) { System.out.println(getIp()); } }}

此時運行結果是

在這里插入圖片描述

可以看的第一臺服務器執行了5次,后面2臺依次執行一次,依次類推。可能你覺得這種算法還不錯。其實這種算法有一個缺點是,如果我第一臺服務器設置權重過大可能我需要很多次請求都執行到第一臺服務器上去,這樣的情況分布是不均勻的,會造成某一臺服務器壓力過大導致崩潰。所以我后面要引入第三種算法來解決這個問題

平滑加權輪詢算法

這種算法可能比較復雜,我第一次看也有點不太明白,后面看過相關資料在結合我自己的理解給大家圖文解釋一下,這里我舉例的服務器配置和權重還是和上面一樣

請求 當前權重 = 自身權重+選中后當前權重 總權重 當前最大權重 返回的ip 選中后當前權重=當前最大權重-總權重
1 {5,1,1} 7 5 192.168.1.1 {-2,1,1}
2 {3,2,2} 7 3 192.168.1.1 {-4,2,2}
3 {1,3,3} 7 3 192.168.1.2 {1,-4,3}
4 {6,-3,4} 7 6 192.168.1.1 {-1,-3,4}
5 {4,-2,5} 7 5 192.168.1.3 {4,-2,-2}
6 {9,-1,-1} 7 9 192.168.1.1 {2,-1,-1}
7 {7,0,0} 7 7 192.168.1.1 {0,0,0}

由上圖可以看出第一臺服務器雖然權重設置的是5,但并不是第五次請求過來都是第一臺服務器執行,而是分散執行,調度序列是非常均勻的,且第 7 次調度時選中后當前權重又回到 {0, 0, 0},實例的狀態同初始狀態一致,所以后續可以一直重復調度操作。

可能有的人還不能清楚的明白上一張圖表示的含義,我這里大概描述一下:

1.首先總權重不會變,默認就是當前設置的權重之和

2.在第一次請求進來的時候我默認初始化當前權重選中值是{0,0,0},所以當前權重的值就是{5+0,1+0,1+0},這里的5,1,1就是我們前面每臺服務器設置的權重。

3.這里我們可以得出第一次請求過來的最大權重是5。然后返回第一臺服務器ip

4.然后我們設置選中后當前權重,這里就是當前最大權重減去總權重(5-7),沒有選中的權重不變,這時候得到當前權重選中權重的值{5-7,1,1}

5.在第二次請求過來的時候我們延續上面的2,3,4步驟執行.

如果這里還有不懂得我下面會提供我自己用java代碼實現的算法:

public class Polling { /** * key是ip,value是權重 */ public static Map <String,Integer> ipService = new LinkedHashMap <>(); static { ipService.put("192.168.1.1",5); ipService.put("192.168.1.2",1); ipService.put("192.168.1.3",1); } private static Map<String,Weight> weightMap = new LinkedHashMap <>(); public static String getIp(){ //計算總的權重 int totalWeight = 0; for (Integer value : ipService.values()) { totalWeight+=value; } //首先判斷weightMap是否為空 if(weightMap.isEmpty()){ ipService.forEach((ip,weight)->{ Weight weights = new Weight(ip, weight,0); weightMap.put(ip,weights); }); } //給map中得對象設置當前權重 weightMap.forEach((ip,weight)->{ weight.setCurrentWeight(weight.getWeight() + weight.getCurrentWeight()); }); //判斷最大權重是否大于當前權重,如果為空或者小于當前權重,則把當前權重賦值給最大權重 Weight maxWeight = null; for (Weight weight : weightMap.values()) { if(maxWeight ==null || weight.getCurrentWeight() > maxWeight.getCurrentWeight()){ maxWeight = weight; } } //最后把當前最大權重減去總的權重 maxWeight.setCurrentWeight(maxWeight.getCurrentWeight() - totalWeight); //返回 return maxWeight.getIp(); } public static void main(String[] args) { //模擬輪詢7次取ip for (int i = 0; i < 7; i++) { System.out.println(getIp()); } }}class Weight{ /** * ip */ private String ip; /** * 設置得權重 */ private int weight; /** * 當前權重 */ private int currentWeight; public Weight(String ip, int weight,int currentWeight) { this.ip = ip; this.weight = weight; this.currentWeight = currentWeight; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public int getWeight() { return weight; } public void setWeight(int weight) { this.weight = weight; } public int getCurrentWeight() { return currentWeight; } public void setCurrentWeight(int currentWeight) { this.currentWeight = currentWeight; }}

這里代碼得執行結果是:

在這里插入圖片描述

可以看出此處執行結果和表格里描述得結果一致。

總結

可能第三種算法理解起來有點復雜,如果看不懂圖表得意思可以先執行下代碼,debugger一步步調試后還是很好理解。

1、輪詢:默認就是這個,按時間順序逐一分配2、權重:按weight權重分配,數字越高比例越高3、指紋:把請求的IP生成hash指紋,統一分配到固定的機器上面4、質量:這個要第三方插件,按后端服務器的響應時間來分配請求,響應時間短的優先分配5、網址:這個要第三方插件,按訪問url的hash結果來分配請求,相同網址相同服務器。用得比較多是第1第2種內容來自www.13333515.buzz請勿采集。


  • 本文相關:
  • 詳解nginx反向代理實現會話(session)保持的兩種方式
  • nginx+tomcat關于session的管理的實現
  • nginx+redis實現session共享
  • nginx+tomcat實現負載均衡,使用redis session共享
  • nginx中共享session會話配置方法例子
  • nginx 負載均衡 多站點共享session
  • nginx worker進程循環的實現
  • nginx根據url中的path動態轉發到upstream的實現
  • nginx搭建基于python的web環境的實現步驟
  • nginx session共享問題解決方案解析
  • nginx rewrite 偽靜態配置參數和使用例子
  • nginx學習之靜態文件服務器配置方法
  • nginx 502 bad gateway和nginx 504 gateway time-out錯誤解決方法
  • nginx配置ssl證書實現https訪問的示例
  • nginx修改配置限制惡意爬蟲頻率
  • nginx自定義訪問日志的配置方式
  • nginx配置限制同一個ip的訪問頻率方法
  • 詳解nginx代理socket.io服務踩坑
  • 一個等號引發的血案(談nginx正確的404配置)
  • 本地https環境搭建的完整步驟記錄
  • NGINX輪詢機制的幾種形式
  • nginx 輪詢失敗,配置了負載均衡,但是請求永遠只訪問其中某一個地址,求大俠指導
  • nginx輪詢有幾種
  • 怎么修改nginx實現均衡負載
  • 如何判斷nginx+tomcat用輪詢的方式一天內分給所有tomcat的請求是否均衡?
  • NGINX部署架構
  • 幾種Nginx實現負載均衡的方式
  • Nginx負載均衡 后端服務器怎么共享Session 問題
  • 求如何Nginx反向代理輪詢Apache web服務
  • 集群是用什么方案實現nginx均衡配置
  • 網站首頁網頁制作腳本下載服務器操作系統網站運營平面設計媒體動畫電腦基礎硬件教程網絡安全星外虛擬主機華眾虛擬主機linuxwin服務器ftp服務器dns服務器tomcat nginxzabbix云和虛擬化服務器其它首頁服務器nginx詳解nginx反向代理實現會話(session)保持的兩種方式nginx+tomcat關于session的管理的實現nginx+redis實現session共享nginx+tomcat實現負載均衡,使用redis session共享nginx中共享session會話配置方法例子nginx 負載均衡 多站點共享sessionnginx worker進程循環的實現nginx根據url中的path動態轉發到upstream的實現nginx搭建基于python的web環境的實現步驟nginx session共享問題解決方案解析nginx rewrite 偽靜態配置參數和使用例子nginx學習之靜態文件服務器配置方法nginx 502 bad gateway和nginx 504 gateway time-out錯誤解決方法nginx配置ssl證書實現https訪問的示例nginx修改配置限制惡意爬蟲頻率nginx自定義訪問日志的配置方式nginx配置限制同一個ip的訪問頻率方法詳解nginx代理socket.io服務踩坑一個等號引發的血案(談nginx正確的404配置)本地https環境搭建的完整步驟記錄nginx提示:500 internal servernginx 多站點配置方法集合權限問題導致nginx 403 forbiddenginx fastcgi錯誤primary scripnginx服務器的反向代理proxy_pasnginx 403 forbidden的解決辦法nginx偽靜態配置和常用rewrite偽nginx下301重定向域名的方法小結詳解nginx服務器中配置超時時間的windows下nginx+php5的安裝與配置nginx處理http請求實例詳解nginx 502 bad gateway 錯誤解決辦法nginx負載均衡配置簡單配置方法基于域名、端口和ip搭建nginx虛擬主機shell腳本之nginx自動化腳本nginx學習之如何搭建文件防盜鏈服務的方法利用nginx解決cookie跨域訪問的方法nginx+ssl+node.js運行環境配置教程nginx下支持thinkphp url rewrite的配置示nginx服務器中設置禁止訪問文件或目錄的方
    免責聲明 - 關于我們 - 聯系我們 - 廣告聯系 - 友情鏈接 - 幫助中心 - 頻道導航
    Copyright © 2017 www.13333515.buzz All Rights Reserved
    3排列五开奖结果