Nginx實現負載均衡的幾種方式
前言
要理解負載均衡,必須先搞清楚正向代理和反向代理。
- 正向代理,代理的是用戶。
- 反向代理,代理的是服務器
正向代理:類似一個跳板機,代理訪問外部資源。比如我們國內訪問谷歌,直接訪問訪問不到,我們可以通過一個正向代理服務器,請求發到代理服,代理服務器能夠訪問谷歌,這樣由代理去谷歌取到返回數據,再返回給我們,這樣我們就能訪問谷歌了
用途:
?。?)訪問原來無法訪問的資源,如google
(2) 可以做緩存,加速訪問資源
(3)對客戶端訪問授權,上網進行認證
?。?)代理可以記錄用戶訪問記錄(上網行為管理),對外隱藏用戶信息

反向代理(Reverse Proxy):實際運行方式是指以代理服務器來接受internet上的連接請求,然后將請求轉發給內部網絡上的服務器,并將從服務器上得到的結果返回給internet上請求連接的客戶端,此時代理服務器對外就表現為一個服務器
作用:
(1)保證內網的安全,阻止web攻擊,大型網站,通常將反向代理作為公網訪問地址,Web服務器是內網
(2)負載均衡,通過反向代理服務器來優化網站的負載
小結
正向代理即是客戶端代理, 代理客戶端, 服務端不知道實際發起請求的客戶端.
反向代理即是服務端代理, 代理服務端, 客戶端不知道實際提供服務的服務端
看圖理解一:

看圖理解二:

正向代理中,proxy和client同屬一個LAN,對server透明;
反向代理中,proxy和server同屬一個LAN,對client透明。
實際上proxy在兩種代理中做的事都是代為收發請求和響應,不過從結構上來看正好左右互換了下,所以把后出現的那種代理方式叫成了反向代理
正向代理: 買票的黃牛
反向代理: 租房的代理
什么是負載均衡
當一臺服務器的單位時間內的訪問量越大時,服務器壓力就越大,大到超過自身承受能力時,服務器就會崩潰。為了避免服務器崩潰,讓用戶有更好的體驗,我們通過負載均衡的方式來分擔服務器壓力。
我們可以建立很多很多服務器,組成一個服務器集群,當用戶訪問網站時,先訪問一個中間服務器,在讓這個中間服務器在服務器集群中選擇一個壓力較小的服務器,然后將該訪問請求引入該服務器。如此以來,用戶的每次訪問,都會保證服務器集群中的每個服務器壓力趨于平衡,分擔了服務器壓力,避免了服務器崩潰的情況。
負載均衡是用反向代理的原理實現的。
在服務器集群中,Nginx起到一個代理服務器的角色(即反向代理),為了避免單獨一個服務器壓力過大,將來自用戶的請求轉發給不同的服務器。
負載均衡用于從“upstream”模塊定義的后端服務器列表中選取一臺服務器接受用戶的請求。一個最基本的upstream模塊是這樣的,模塊內的server是服務器列表:
#動態服務器組
upstream dynamic_zuoyu {
server localhost:8080; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082; #tomcat 8.5
server localhost:8083; #tomcat 9.0
}
在upstream模塊配置完成后,要讓指定的訪問反向代理到服務器列表:
#其他頁面反向代理到tomcat容器
location ~ .*$ {
index index.jsp index.html;
proxy_pass http://dynamic_zuoyu;
}
這就是最基本的負載均衡實例,但這不足以滿足實際需求;目前Nginx服務器的upstream模塊支持6種方式的分配:
| 輪詢 | 默認方式 |
| weight | 權重方式 |
| ip_hash | 依據ip分配方式 |
| least_conn | 最少連接方式 |
| fair(第三方) | 響應時間方式 |
| url_hash(第三方) | 依據URL分配方式 |
負載均衡的幾種常用方式
1、輪詢(默認)
最基本的配置方法,上面的例子就是輪詢的方式,它是upstream模塊默認的負載均衡默認策略。每個請求會按時間順序逐一分配到不同的后端服務器。
有如下參數:
| fail_timeout | 與max_fails結合使用。 |
| max_fails |
設置在fail_timeout參數設置的時間內最大失敗次數,如果在這個時間內,所有針對該服務器的請求都失敗了,那么認為該服務器會被認為是停機了,
|
| fail_time | 服務器會被認為停機的時間長度,默認為10s。 |
| backup | 標記該服務器為備用服務器。當主服務器停止時,請求會被發送到它這里。 |
| down | 標記服務器永久停機了。 |
注意:
- 在輪詢中,如果服務器down掉了,會自動剔除該服務器。
- 缺省配置就是輪詢策略。
- 此策略適合服務器配置相當,無狀態且短平快的服務使用。
2、weight
指定輪詢幾率,weight和訪問比率成正比,用于后端服務器性能不均的
情況。
# 動態服務器組
upstream dynamic_zuoyu {
server localhost:8080 weight=2; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082 backup; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}
# 示例二
upstream backserver {
server 192.168.0.14 weight=3;
server 192.168.0.15 weight=7;
}
# 權重越高,在被訪問的概率越大,如上例,分別是30%,70%。
在動態服務器組的例子中:weight參數用于指定輪詢幾率,weight的默認值為1,;weight的數值與訪問比率成正比,比如Tomcat 7.0被訪問的幾率為其他服務器的兩倍。
注意:
- 權重越高分配到需要處理的請求越多。
- 此策略可以與least_conn和ip_hash結合使用。
- 此策略比較適合服務器的硬件配置差別比較大的情況。
3、ip_hash
上述方式存在一個問題就是說,在負載均衡系統中,假如用戶在某臺服務器上登錄了,那么該用戶第二次請求的時候,因為我們是負載均衡系統,每次請求都會重新定位到服務器集群中的某一個,那么已經登錄某一個服務器的用戶再重新定位到另一個服務器,其登錄信息將會丟失,這樣顯然是不妥的。
我們可以采用ip_hash指令解決這個問題,如果客戶已經訪問了某個服務器,當用戶再次訪問時,會將該請求通過哈希算法,自動定位到該服務器。
每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個后端服務器,可以解決session的問題。
#動態服務器組
upstream dynamic_zuoyu {
ip_hash; #保證每個訪客固定訪問一個后端服務器
server localhost:8080 weight=2; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}
# 示例二
upstream backserver {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}
# 示例三:此負載均衡策略適合請求處理時間長短不一造成服務器過載的情況。
upstream dynamic_zuoyu {
least_conn; #把請求轉發給連接數較少的后端服務器
server localhost:8080 weight=2; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082 backup; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}
4、fair(第三方)
按后端服務器的響應時間來分配請求,響應時間短的優先分配。
upstream backserver {
server server1;
server server2;
fair;
}
5、url_hash(第三方)
按訪問url的hash結果來分配請求,使每個url定向到同一個后端服務器,要配合緩存命中來使用。同一個資源多次請求,可能會到達不同的服務器上,導致不必要的多次下載,緩存命中率不高,以及一些資源時間的浪費。而使用url_hash,可以使得同一個url(也就是同一個資源請求)會到達同一臺服務器,一旦緩存住了資源,再此收到請求,就可以從緩存中讀取。
#動態服務器組
upstream dynamic_zuoyu {
hash $request_uri; #實現每個url定向到同一個后端服務器
server localhost:8080; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082; #tomcat 8.5
server localhost:8083; #tomcat 9.0
}
# 示例二
upstream backserver {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}
每個設備的狀態設置為:
1.down 表示單前的server暫時不參與負載
2.weight 默認為1.weight越大,負載的權重就越大。
3.max_fails:允許請求失敗的次數默認為1.當超過最大次數時,返回proxy_next_upstream模塊定義的錯誤
4.fail_timeout:max_fails次失敗后,暫停的時間。
5.backup: 其它所有的非backup機器down或者忙的時候,請求backup機器。所以這臺機器壓力會最輕。
配置實例:
#user nobody;
worker_processes 4;
events {
# 最大并發數
worker_connections 1024;
}
http{
# 待選服務器列表
upstream myproject{
# ip_hash指令,將同一用戶引入同一服務器。
ip_hash;
server 125.219.42.4 fail_timeout=60s;
server 172.31.2.183;
}
server{
# 監聽端口
listen 80;
# 根目錄下
location / {
# 選擇哪個服務器列表
proxy_pass http://myproject;
}
}
}
未完待續……

浙公網安備 33010602011771號