nginx負載均衡

       在業界,一直流傳這樣一句話:Nginx抗併發能力強!爲什麼Nginx抗併發能力強?原因是使用了非阻塞、異步傳輸
阻塞:如apache代理tomcat時,apache開啓10個進程,同時處理着10個請求,在tomcat沒有返回給apache結果時,apache是不會處理用戶發出的第11個請求
非阻塞:如nginx代理tomcat時,nginx開啓1000個併發,同時處理着1000個請求,在tomcat沒有返回給nginx結果時,nginx會依然處理後面用戶發給的請求
同步傳輸:比如squid代理tomcat時,瀏覽器發起請求,然後請求會squid立刻被轉到後端服務器,於是在瀏覽器和後端服務器之間就建立了一個連接。在請求發起到請求完成,這條連接都是一直存在的。
異步傳輸:比如nginx代理tomcat時,瀏覽器發起請求,請求不會立刻轉到後端服務器,而是將請求數據(header)先保存到nginx上,然後nginx再把這個請求發到後端服務器, 後端服務器處理完之後把數據返回到nginx上,nginx將數據流發到瀏覽器。
1.png 
     如上圖所示假設用戶執行一個上傳文件操作,由於用戶網速較慢,因此需要花半個小時才能把文件傳到服務器。squid的同步代理在用戶開始上傳後就和後端tomcat建立了連接,半小時後文件上傳結束,所以,後端tomcat服務器連接保持了半個小時;而nginx異步代理就是先將數據保存在nginx上,因此僅僅是nginx和用戶 保持了半小時連接,後端服務器在這半小時內沒有爲這個請求開啓連接,半小時後用戶上傳結束,nginx纔將上傳內容發到後端tomcat,nginx和後臺之間的帶寬 是很充裕的,所以只花了一秒鐘就將請求發送到了後臺,由此可見,後端服務器連接保持了一秒。

一、負載均衡
1、負載均衡模塊(upstream)
Upstream模塊是Nginx 負載均衡的主要模塊,它提供了簡單的辦法來實現在輪詢和客戶端IP之間的後端服務器負載均衡,並可以對服務器進行健康檢查。upstream並不處理請求,而是通過請求後端服務器得到用戶的請求內容。在轉發給後端時,默認是輪詢,也可以是ip_hash。

Nginx常見負載均衡方式
輪詢(默認):按照每個請求時間的順序的分配到後端服務器
ip_hash:每個請求按訪問ip的hash結果分配
weight:按照權重輪詢,權重值越高,輪詢機率越大 
fair(三方):按後端服務器的響應時間來分配請求,響應時間短的優先分配
url_hash(三方):根據url的hash結果進行分配

下面爲一組服務器負載均衡的集合:
upstream info_pool {
                     ip_hash;
                     server 110.4.111.28:8081 max_fails=2 fail_timeout=5s;
                     server 110.4.111.29:8081 max_fails=2 fail_timeout=5s;
                     server 110.4.111.30:8081 max_fails=2 fail_timeout=5s;
                     } 

Upstream相關指令解釋:
max_fails:定義定義可以發生錯誤的最大次數
fail_timeout:nginx在fail_timeout設定的時間內與後端服務器通信失敗的次數超過max_fails設定的次數,則認爲這個服務器不在起作用;在接下來的 fail_timeout時間內,nginx不再將請求分發給失效的server
down:把後端標記爲離線,僅限於ip_hash
backup:標記後端爲備份服務器,若後端服務器全部無效時才啓用

upstream中使用ip_hash模式時,爲什麼weight選項會被忽略?
因爲ip_hash模式使用的負載均衡算法是根據請求ip進行hash,而weight模式使用的wrr算法,所以不可同時使用

2、代理模塊(proxy)
    Proxy爲Nginx的代理模塊,允許負責將用戶的HTTP請求轉發到後端服務器,同時也可以結合upstream模塊,達到負載均衡的目的
注:proxy相關功能、指令很多,在此只講與upstream相關的指令和功能

proxy模塊常用指令解釋:
proxy_pass:指定轉發到後端服務器的請求,在location中指定,常用URI類型如下
TCP套接字:proxy_pass http://127.0.0.1:8080; 
Unix套接字:proxy_pass http://unix:/tmp/nginx.sock;
Upstream區段:proxy_pass http://nginx_pool;
域名:proxy_pass http://www.a.com;

proxy_pass使用域名命名時,爲什麼不能和server_name相同 ?
nginx解析.jpg 
如上圖所以,其數據訪問流如下:
①        、用戶訪問www.a.com,server_name指令監聽並接受www.a.com請求內容
②        、server_name將www.a.com的請求轉交給proxy_pass指令處理
③        、proxy_pass接到請求後根據相應URI進行處理(此處URI爲www.a.com),因爲我們此處URI爲域名,所以proxy_pass會請求DNS進行解析
④        、proxy_pass收到DNS解析結果(www.a.com),去請求server_name
由此可見如果proxy_pass的URI命名若和server_name命名相同,則形成一個請求環路。所以在配置proxy_pass的URI時,應避免和本server內的server_name重名


二、健康檢查
   Nginx的健康檢查主要體現在對後端服務提供健康檢查,且功能被集成在upstream模塊中,共有兩個指令
max_fails:定義定義可以發生錯誤的最大次數
fail_timeout:nginx在fail_timeout設定的時間內與後端服務器通信失敗的次數超過max_fails設定的次數,則認爲這個服務器不在起作用;在接下來的 fail_timeout時間內,nginx不再將請求分發給失效的server。
健康檢查機制:
   Nginx在檢測到後端服務器故障後,nginx依然會把請求轉向該服務器,當nginx發現timeout或者refused後,會把改請求會分發到upstream的其它節點,直到獲得正常數據後,nginx纔會把數據返回給用戶,這也便體現了nginx的異步傳輸,而lvs/haproxy/apache責無法做到這些(在lvs/haproxy/apache裏,每個請求都只有一次機會,假如用戶發起一個請求,結果該請求分到的後端服務器剛好掛掉了,那麼這個請求就失敗了)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章