Nginx 動靜分離與負載均衡的實現

choubou發表於2021-09-09


一、前提

       企業中,隨著使用者的增長,資料量也幾乎成幾何增長,資料越來越大,隨之也就出現了各種應用的瓶頸問題。

       問題出現了,我們就得想辦法解決,一般網站環境,均會使用LAMP或者LNMP,而我們對於網站環境的最佳化,除了對原始碼進行最佳化、SQL慢查詢最佳化 、SQL建立索引等之外,我們還可以對環境架構進行最佳化與擴充套件。

       因此,我們引入了 Nginx 對站點實現負載均衡和動靜分離,來加快訪問速度。

二、Nginx 動靜分離與負載均衡的實現機制

       Nginx 動靜分離與負載均衡的的實現離不開反向代理,什麼是反向代理呢?反向代理主要應用於叢集環境中,有多個客戶端給Nginx伺服器傳送的請求,當 Nginx 伺服器接收到之後,會按照一定的規則將請求分發給了後端的業務處理伺服器,此時,請求的來源也就是客戶端,是明確的,但是請求具體由哪臺伺服器處理,並不明確,在這裡,Nginx 所扮演的就是一個反向代理角色。透過反向代理,我們無法直接看到後端伺服器的伺服器資訊,因此反向代理具有隱藏業務伺服器的作用!

三、Nginx 反向代理實現

       1、網路拓撲

        圖片.png

       2、環境準備

       圖片.png

       我們準備好7臺伺服器,2 臺 MySQL 資料庫做高可用,4 臺 Web 伺服器,其中 2 臺裝 Nginx+PHP 做動態頁面的負載均衡,另外 2 臺裝 Apache+PHP 做靜態頁面的負載均衡,1 臺 Nginx 伺服器,做反向代理伺服器。

       至於,伺服器環境的安裝部署,這裡就不進行操作了,如有疑問的,可以留言或者檢視小弟前面的文章。

       3、Nginx 伺服器中 Nginx 服務配置檔案修改

       修改 http 部分

       [root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf

       圖片.png

      1、重新定義 Nginx 服務的日誌記錄格式,關於關鍵字的釋義,大佬們可以參閱官網。

      2、使用 upstream 關鍵字定義後端伺服器

            格式:uptream + 後端節點組名稱(可自定義)

            server + IP地址 + 權重 + 最大失敗次數 + 失敗超時時間             意思是:當後端節點連續兩次在3秒內無法連線時,將放棄連線該節點,Nginx 將客戶端請求傳送給下一節點。

      修改 server 部分,這裡配置為 Nginx 虛擬機器

      [root@nginx ~]# vim /wdata/nginx/config/80.conf

      圖片.png

      1、配置 Nginx location 匹配

           分別配置以 .html 、.jpeg 、.jpg 、.gif 、.png 、.php 為副檔名的檔案的 location 規則。

           proxy_set_header:允許重新定義或新增欄位傳遞給代理伺服器的請求頭。該值可以包含文字、變數和它們的組合。在本例中意思將真實的客戶端地址新增到代理伺服器的請求頭中。

           proxy_pass:設定反向代理的連線,格式為:proxy_pass + http://後端節點組的名稱; 。 

           X-Forwarded-For:簡稱 XFF 頭,它代表客戶端,也就是 HTTP 的請求端真實的 IP ,只有在透過了 HTTP 代理或者負載均衡伺服器時才會新增該項。

           $remote_addr:遠端地址,也就是客戶端 IP 地址

      2、配置站點日誌,這裡將日誌格式指定為我們在 HTTP 部分配置為的 main 規則。

      Nginx 反向代理的配置請參照圖中進行修改,其他詳細的配置引數,請參閱官網,後續繼續更新。

四、後端 Nginx 服務節點配置

      後端 Nginx 伺服器節點主要用來做以 .php 副檔名結尾的站點檔案的訪問和圖片檔案的訪問,做到將圖片資源單獨剝離,以降低伺服器負載。

      1、配置以 .php 為副檔名的站點伺服器

      [root@weba config]# vim 80.conf

      圖片.png

      如上圖:

      a、listen:配置監聽埠,這裡配置為 80 埠,在生產環境中,我們可能會配置成 443 埠。

           server_name:配置域名,這裡是實驗環境,因此採用預設未配置域名。

           index:配置支援的檔案型別

           root:配置全域性站點路徑

      b、配置區域性站點路徑、fastcgi的地址埠(指的是php-fpm的監聽地址及埠)、所支援的檔案型別等

      c、配置日誌檔案

      Nginx 站點的配置大概做到這種配置,基本就可以進行訪問,如果在企業中需要更復雜的配置,請參考官方文件。

      2、配置單獨的圖片資源站點

      [root@weba config]# vim 81.conf

      圖片.png

      如上圖:

      配置方式跟 1 的配置完全一樣,只是修改一下圖片資源的路徑即可。

      WebA 和 WebB 的配置完全一樣。最後修改完配置別忘了重新整理,用命令:service nginx reload 即可

五、後端 Apache 服務節點配置

      1、Apache 服務節點的配置基本也跟 Nginx 差不多,我們這裡使用命令修改 Apache 配置檔案。

      [root@webc ~]# sed -i "s#/home/wwwroot/default#/wdata/http/www#g" /usr/local/apache/conf/httpd.conf

      [root@webc ~]# sed -i "s#/home/wwwroot/default#/wdata/http/www#g" /usr/local/apache/conf/extra/httpd-vhosts.conf

      [root@webc ~]# sed -i "s#/var/log/wwwlogs#/var/log/wwwlogs#g" /usr/local/apache/conf/httpd.conf

      [root@webc ~]# sed -i "s#/var/log/wwwlogs#/var/log/wwwlogs#g" /usr/local/apache/conf/extra/httpd-vhosts.conf

      [root@webc ~]# sed -i "s#/var/www#/wdata/http/www#g" /usr/local/apache/conf/extra/httpd-vhosts.conf

      在 WebC 和 WebD 中分別執行,主要設定網站根目錄和日誌目錄。

      2、修改 Apache 的埠和監聽地址

      [root@webc ~]# vim /usr/local/apache/conf/httpd.conf

      找到 Listen 行,修改為 0.0.0.0:80

      如圖:

      圖片.png

      3、修改 Apache 日誌檔案格式,方便我們更好閱讀 Apache 日誌,也可以保持預設。

      找到 <IfModule log_config_module> 行,在下面的註釋下面新增

      LogFormat "%a - %A %t "%B" "%b" "%{Foobar}C" "%f" - %h - %H "%{Foobar}i" %m "%{Foobar}n" "%{Foobar}o" - "%p" - "%P" %q %r %s "%T" "%u" "%U" "%v" "%V" %X" main

      如圖:

      圖片.png

      至於所新增的引數的含義,大家可參閱 Apache 官方文件。

      到此 Apache 配置完成,還有一些關於 Apache 的許可權配置等,這裡就先不做特殊說明,後期再做更新。

      啟動 httpd 服務:

      service httpd start

六、新增或者上傳站點檔案

      1、在 WebA 中的網站根目錄下新增 index.php 檔案,內容如下:

            <html>

            <title>

                       This is a PHP page

            </title>

            <body>

                       Real ServerA<br><br>

                       <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="1.jpg"  alt="1" height="200" width="200" />

                       <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="2.jpg"  alt="2" height="200" width="300" />

                       <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="3.png"  alt="3" height="200" width="200" />

                       <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="4.gif"  alt=“4" height="200" width="380" /><br><br>

                       This is a PHP page !<br><br>

            </body>

            </html>

            <?php

            $link = new mysqli("192.168.20.150","root","123456");

            if(!$link) echo "FAILD!連線錯誤,使用者名稱密碼不對";

            else echo "OK ! MySQL 可以連線。";

            $link->close();

            ?>

      2、在 WebB 中的網站根目錄下新增 index.php 檔案,內容如下:

            <html>

            <title>

                       This is a PHP page

            </title>

            <body>

                       Real ServerB<br><br>

                       <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="1.jpg"  alt="1" height="200" width="200" />

                       <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="2.jpg"  alt="2" height="200" width="300" />

                       <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="3.png"  alt="3" height="200" width="200" />

                       <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="4.gif"  alt=“4" height="200" width="380" /><br><br>

                       This is a PHP page !<br><br>

            </body>

            </html>

            <?php

            $link = new mysqli("192.168.20.150","root","123456");

            if(!$link) echo "FAILD!連線錯誤,使用者名稱密碼不對";

            else echo "OK ! MySQL 可以連線。";

            $link->close();

            ?>

      說明:這裡,我們並沒有嚴格按照 PHP 檔案的格式來書寫,只是簡單的為了驗證負載均衡和反向代理來書寫的 PHP 檔案。

      3、在 WebA 和 WebB 的 image(圖片資源目錄) 目錄上傳 1.jpg 、2.jpg 、3.png 、4.gif 檔案,如圖:

      圖片.png

      4、在 WebC 的站點根目錄新增 index.html 檔案,內容如下:

      <html>

      <title>

                 This is a HTML page

      </title>

      <body>

                 Real ServerC<br><br>

                 <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="1.jpg"  alt="1" height="200" width="200" />

                 <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="2.jpg"  alt="2" height="200" width="300" />

                 <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="3.png"  alt="3" height="200" width="200" />

                 <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="4.gif"  alt=“4" height="200" width="380" /><br><br>

                 This is a HTML page !

       </body>

       </html>

      5、在 WebD 的站點根目錄新增 index.html 檔案,內容如下:

      <html>

      <title>

                 This is a HTML page

      </title>

      <body>

                 Real ServerD<br><br>

                 <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="1.jpg"  alt="1" height="200" width="200" />

                 <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="2.jpg"  alt="2" height="200" width="300" />

                 <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="3.png"  alt="3" height="200" width="200" />

                 <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="4.gif"  alt=“4" height="200" width="380" /><br><br>

                 This is a HTML page !

       </body>

       </html>

      檔案新增和上傳完成,下面我們開始驗證我們配置的動靜分離和負載均衡是否成功。

七、驗證動靜分離和負載均衡

      1、在瀏覽中開啟 http://192.168.20.138/index.php ,效果如下圖:

      圖片.png

      圖片.png

     2、在瀏覽器 http://192.168.20.138/index.html ,效果如下圖:

      圖片.png

      圖片.png

     3、檢視 Nginx 負載均衡器的 Nginx 日誌。

       訪問 http://192.168.20.138/index.php  日誌如下圖:    圖片.png

       如圖可以看出,當我們訪問 http://192.168.20.138/index.php 時,伺服器會將客戶端請求按照我們配置的後端節點組中的順序或者權重依次發給 WebA 和 WebB ,當網頁中有圖片請求時,也會按照順序進行訪問 WebA 和 WebB 的圖片節點。

     訪問 http://192.168.20.138/index.html  日誌如下圖:

圖片.png

        如圖可以看出,當我們訪問 http://192.168.20.138/index.html 時,對於 html 的請求,會依次發給 WebC 和 WebD 節點服務,而對於圖片資源的訪問,會將請求發給兩臺圖片伺服器。

由以上日誌可以看出,Nginx 配置動靜分離和負載均衡時一件很簡單的工作,配置過程,需要我們認真對待。

八、總結

      經過前面配置與測試,我們發現,Nginx 反向代理動靜分離、負載均衡很簡單,只需要我們會使用兩個關鍵字:upstream 和 proxy_pass 即可,會使用這兩個關鍵字,基本的反向代理動靜分離、負載均衡是完全可以實現,但是在實際的生產環境中,需要我們做的還有很多。

©著作權歸作者所有:來自51CTO部落格作者司徒曉宇的原創作品,如需轉載,請註明出處,否則將追究法律責任


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4548/viewspace-2821696/,如需轉載,請註明出處,否則將追究法律責任。

相關文章