負載均衡-Nginx深入探究

Nginx是一個反向代理服務器,其負載均衡也是基於反向代理來實現的,所以先來理解一下什麼是反向代理.

1 反向代理

1.1 反向代理原理圖:

這裏寫圖片描述

1.2 什麼是反向代理呢?

如上圖所示,當瀏覽器當瀏覽器向服務器發出url請求,nginx會檢查這個uri要執行什麼樣的指令,也就是說要執行什麼樣的location指令,它根據這個location要進行什麼樣的操作.如果當前這個location配置完要進行一個代理的操作,把這個請求轉交個後端服務器進行操作,這個時候呢是從nginx本身來發起一個請求,對於這個後端服務器來說呢,nginx就是它的前臺客戶端,或者說它認爲Nginx就是一個瀏覽器,後端服務器有自己的iq和端口(或者說有它自己的域名),Nginx是基於這個域來發給tomcat所在的域.後面的uri和前面請求的uri是一樣的,也就是說這個uri拿過來,然後找到tomcat所在域中的uri,完成對tomcat的請求.tomcat處理完結果將結果返回給nginx,nginx將結果返回瀏覽器.這樣就完成了我們整個處理過程.對於瀏覽器來說,它並不知道後端tomcat服務器的存在,只是覺得將請求發給nginx後得到一個相應;對於tomcat也是一樣的,只是覺得有nginx這個前臺客戶端的存在.這就是代理的過程.

1.3 反向代理詳細配置

假設本機在內網的ip是192.168.1.111,我們要通過Nginx來轉發對192.168.1.111的80端口的請求到192.168.1.112的8080端口上,具體有如下配置:

server{
        listen       80;
        server_name  www.zhishe.pub;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        error_log logs/error.log;

        port_in_redirect off;

        location / {
            #root   /html;
            index  index.html index.htm;
            proxy_pass http://192.168.1.112:8080;
        }

        error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

}

同樣的道理,對於php的解析也是一樣,用相似的方法來轉發對php文檔的請求.通過9000端口上的php-fpm下的php-cgi
具體如下:

location ~ \.php$
        {
            #指定爲Nginx默認路徑
            root /opt/nginx/html/wordpress;
            對所有php文件的訪問統一交給9000端口處理
            fastcgi_pass  127.0.0.1:9000;
            默認訪問
            fastcgi_index index.php;
        文件請求路徑
        fastcgi_param SCRIPT_FILENAME /opt/nginx/html$fastcgi_script_name;

        fastcgi_param QUERY_STRING $query_string; #請求的參數;如?app=123 
        fastcgi_param REQUEST_METHOD $request_method; #請求的動作(GET,POST) 
        fastcgi_param CONTENT_TYPE $content_type; #請求頭中的Content-Type字段 
        fastcgi_param CONTENT_LENGTH $content_length; #請求頭中的Content-length字段。 

        fastcgi_param SCRIPT_NAME $fastcgi_script_name; #腳本名稱 
        fastcgi_param REQUEST_URI $request_uri; #請求的地址不帶參數 
        fastcgi_param DOCUMENT_URI $document_uri; #與$uri相同。 
        fastcgi_param DOCUMENT_ROOT $document_root; #網站的根目錄。在server配置中root指令中指定的值 
        fastcgi_param SERVER_PROTOCOL $server_protocol; #請求使用的協議,通常是HTTP/1.0或HTTP/1.1。 

        fastcgi_param GATEWAY_INTERFACE CGI/1.1;#cgi 版本 
        fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;#nginx 版本號,可修改、隱藏 

        fastcgi_param REMOTE_ADDR $remote_addr; #客戶端IP 
        fastcgi_param REMOTE_PORT $remote_port; #客戶端端口 
        fastcgi_param SERVER_ADDR $server_addr; #服務器IP地址 
        fastcgi_param SERVER_PORT $server_port; #服務器端口 
        fastcgi_param SERVER_NAME $server_name; #服務器名,域名在server配置中指定的server_name 
            include fastcgi.conf;
            include fastcgi_params;
        }

2 負載均衡

2.1 負載均衡原理圖:

這裏寫圖片描述
負載均衡的實驗原理類似於反向代理的設置.如上圖,如果後端之後一個服務器那麼nginx的作用就是一個只是起到了一個反向代理的作用,如果後端有多個服務器,那麼一個請求到達Nginx就會按照一定策略來決定當前的請求發給其中的某一個;如果有多個請求進來的時候,多個請求會按照策略分發到不同的服務器上,多個服務器分擔了來自前臺的請求.最後就這樣多個後端服務器分擔了前端的負載,達到了我們所說的負載均衡.所以說負載均衡的具體實現是:首先我們有多個服務器形成的服務器組,然後Nginx通過反向代理將請求轉發到服務器組上,其中分配策略是通過Nginx內部配置來實現的.所以說負載均衡要設置的是這三層的概念.

2.2 具體實現步驟

2.2.1 服務器組的基本設置以及基本的輪詢式均衡策略:

通過如上的配置我們就定義好了一個服務器組.對應之前的反向代理的轉發路徑也要進行修改.根據上面的默認配置,當前的發送的一個請求轉發的tomcats服務器組,我們什麼也沒填,他就是一個平均的轉發策略,每個服務器接受一個請求,依次輪詢.

2.2.2 upstream裏面設置server的其他常用參數

upstream backends{
    #均衡策略
    #none 輪詢(權重由weight來決定)

    #ip_hash
        當用戶發送一個請求,它會把客戶端的ip地址進行一個hash運算,然後根據得到的值把它分配在一個服務器上.下次該用戶再次訪問的時候,用戶的IP沒有變,對應的hash算法的沒有變,用戶還是在之前的服務器上.最終會出現這麼一個類似的結果,某個用戶被粘在這一臺服務器上,除非該服務器掛掉,否則,該用戶訪問總是這一臺服務器.當有多個用戶的時候,就通過hash算法將多個用戶平均分配到多個服務器上,這就是ip_hash的作用.然而這種方式會讓權重設置失效,因爲該種方式是適合於數據量比較大的情況下,最終會完成一個平均分佈,因此設置權重是沒有意義的.
用法是直接加到服務器組上,對應的一組服務器都是用的ip_hash的策略.

    第三方策略
    #fair:自己管理後端服務器的權重,誰的響應能力強,誰的權重就高.動態地根據後端的負載來判斷,所以說這是一個比較人性化的負載均衡策略.
    #url_hash:類比ip_hash,這裏是將url進行hash運算綁定.同一個url定位到同一個服務器上,不同的url定位到不同的服務器上.
    #這個比較適合用於電子商務網站,有大量的商品信息,所有的商品通過靜態化形成了靜態頁面,然後我們的服務器通過緩存的方式,把相應的靜態頁面按照命中率高的放到緩存裏來加快訪問的速度,也就是說實現了一個基於緩存的服務器,這個時候我們使用url_hash就是一個比較適合的場景.爲什麼這麼說呢,每一個商品都有一個唯一的url,同一個商品不管哪個用戶來訪問,它的url是相同的,所以說它的url_hash值也是相同的,通過這樣的url_hash策略,不管哪個用戶訪問都到相同的服務器上來獲取信息,有多個服務器就緩存了多個不同的商品,一旦相同的商品,hash值會映射到相同的服務器上,另外的服務器會不加載該商品.所以說大量不同的商品分別在不同的服務器上緩存起來,達到平均把緩存平均負載到後端服務器上的目的.這個時候呢通過url_hash的策略就會加快訪問的速度。
    用法同ip_hash,因爲是第三方策略,所以說默認的策略中是沒有的,具體見下面第三小節。

    #weight:權重,值越高負載越大;
    #當服務器的爲如第一小節所示的配置的時候,所有的服務器的權重都是一樣的.
    #假如有一臺服務器如下64的,它的性能比起62,63兩臺服務器高很多
    #,如果還是用之前的均衡策略顯然不適合,所用通過weight來增加它的權重.
    #如下設置,64的權重爲5,另外兩個爲1,所以64佔整個所有請求的5/7,另外兩個各佔1/7.
    server 192.168.1.62:8080;
    server 192.168.1.63;
    server 192.168.1.64 weight=5;

    #backup:備份機,只有在所有的正在工作的服務器都掛掉之後纔會啓用
    #,來起到臨時備用的作用.正常情況下是不會參與均衡的負載.
    server 192.168.1.65 backup;

    #down:停機標誌,不會被訪問.設有該標誌的服務器是停止的
    #,無論什麼情況下都不會把請求發送到這裏.                                       
    #(尤其是當你要對該服務器進行硬件的更換或者出現臨時狀況要進行修復需要該參數,
    如果不進行該設置而是直接關停對應的服務器,
    #請求還是認爲該機器是可以訪問的,就會不停地嘗試訪問這臺服務器,
    #得到一個錯誤的結果,造成整個請求時間上的浪費.所以它就是我們臨時維護時候的一個停機標誌.)
    server 192.168.1.66 down;

    #max_fails:達到指定次數認爲服務器掛掉;
    #fail_timeout:掛掉之後多久再去測試是否已經恢復;
    #默認情況下,每個服務器都會有該項配置,只是不是顯示配置的時候都是默認值.
    #如下配置,假設當它發生了故障之後,請求發到67的時候,沒有響應
    #,它並不認爲67已經掛掉了,而是第二次到達之後還是沒有收到響應.
    #此時纔將該臺ip爲67的服務器標記爲失敗的狀態.在失敗的期間內,請求是不會發送到67.
    #對應的失敗期間的時長就是我們的另一個參數,file_timeout.
    server 192.168.1.67 Imax_fails=2 fail_timeout=60s;
}

2.2.3 對應的第三方策略的下載安裝

以fair爲例:
下載如下安裝包:
nginx-upstream-fair-master.zip
解壓之後會有兩個文件:config ngx_http_-upstream_fair-master.c
安裝方式是在nginx源碼編譯安裝的時候一塊編譯的,對應的方式(兩道短橫線):
./configure –prefix=/opt/nginx –add-module=/tmp/nginx-upstream-fair-master
如果是第一次安裝nginx 接着:make && make install
到objs查看編譯結果,把nginx的二進制文件替換之前的sbin目錄下的原來的文件,然後再啓動.
對應的url_hash也是一樣.

發佈了45 篇原創文章 · 獲贊 30 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章