1. 程式人生 > >每個Java 程式設計師都應該要掌握的 Nginx 實戰應用

每個Java 程式設計師都應該要掌握的 Nginx 實戰應用

說到 Nginx,專案中一般是運維人員在負責這塊內容,Java 程式設計師在開發中反而不怎麼會具體使用。程式設計師知道 Nginx 可以實現反向代理、負載均衡、動靜分離等功能,工作中不會實際地去配置這些內容,也不清楚具體是怎麼在 Nginx 中實現這些功能。那麼通過看這篇 文章也許會讓你有所收穫。

本篇 文章 以例項演示, 從以下 10 個方面對 Java 程式設計師應掌握的 Nginx 知識進行講解:

希望通過本篇文章的學習,使一執行緒序員快速瞭解常用的 Nginx 相關知識點,瞭解 Nginx 是如何做到反向代理、負載均衡、動靜分離、實現防盜鏈,以及解決跨域問題。

一、常用的 Web 伺服器介紹

伺服器介紹

Web 伺服器分為靜態伺服器和動態伺服器,靜態伺服器就是處理靜態資源的,比如 HTML、CSS、JS,常用的靜態伺服器有 Apache、Nginx;動態伺服器就是處理動態請求的,比如 JSP,Servlet 等,常用的有 Tomcat、Weblogic。

Nginx 是一個高效能的 HTTP 伺服器和反向代理伺服器,能夠支援 5 萬個併發連線,記憶體、CPU 消耗非常低,是基於七層協議的服務。

反向代理介紹

我們平時說的代理指的是代理客戶端,這個是正向代理,反向代理指的是代理服務端。

我們作為使用者想訪問一個服務資源 URL,如果我們的瀏覽器直接打不開這個 URL,一般會通過 VPN 或者其他代理伺服器中轉,這種情況下的代理就是正向代理,也就是我們通常說的代理的意思。

而反向代理是指,作為服務資源提供方,內部有很多伺服器,這些伺服器不能全部暴露給第三方使用者,因此需要在內部伺服器的前面加一個代理伺服器,使用者訪問的是代理服務的 IP,而不知道具體訪問的是服務端的哪臺機器,這種情況就是反向代理,指的是代理服務端。

二、Nginx 在分散式架構中的作用

分散式架構的演進

一個網站的初期,訪問的流量比較小,選用的架構可能就是使用者通過域名訪問,經過域名解析(DNS 伺服器),拿到後端伺服器的 IP 地址,直接訪問到這個 IP 所對應的 Tomcat 伺服器,這是最簡單的一個網站架構。

隨著使用者流量的增大,一臺 Tomcat 伺服器無法滿足使用者的請求,因此人們會想到 2 個辦法:

        1.升級這臺伺服器更換更強大的硬體,這就是垂直擴充套件;

        2.增加新的伺服器來分擔前端流量,這就是水平擴充套件。

垂直擴充套件的方式就是對一臺伺服器不斷加強硬體,但是伺服器的可擴充套件記憶體會有上限,總會達到瓶頸,而且成本比較高,因此人們一般會選擇水平擴充套件。一臺不夠再加一臺,不行再加一臺......

為了應對流量的增加,不斷地增加後端伺服器的數量,那麼伺服器的 IP 會越來越多,通過 DNS 伺服器管理這些伺服器 IP 帶來了新的問題:

後端的某臺機器宕機後,DNS 伺服器不知道該機器宕機,仍然解析到了這個 IP,如果使用者訪問到了這個宕機的 IP,那麼系統無法為使用者提供服務;

DNS 伺服器配置新的 IP 後,它不會立即生效,那麼在它生效的這個時間段,新加的伺服器不會為使用者提供服務。

反向代理和負載均衡伺服器可以很好地解決上面的問題。

用了反向代理伺服器後,網站的架構就進一步演進,變成了使用者通過域名訪問,DNS 伺服器返回反向代理伺服器的 IP,反向代理伺服器根據被代理伺服器的 IP 配置和負載均衡的策略,轉發使用者的請求到不同的後端伺服器,後端伺服器返回響應結果到反向代理伺服器,反向代理伺服器返回結果給使用者。

反向代理伺服器因為只轉發使用者的請求而不做具體處理,因此它的效能比應用伺服器強大。

隨著流量的繼續增大,單臺反向代理伺服器成為了瓶頸,我們就會對其做叢集,解決高效能的問題,對其做主備解決高可用的問題。

至此,一個網站的分散式架構的演進過程介紹完了。

Nginx 在分散式架構的作用

通過上面的架構演進介紹,我們知道分散式架構中最重要的思路就是水平擴充套件,水平擴充套件最重要的一個環節就是反向代理和負載均衡。

Nginx 就是一個高效能的反向代理和負載均衡伺服器,它可以支援 5 萬的併發訪問,同時它可以做動靜分離,可以解決跨域訪問和防盜鏈的問題。

三、Nginx 的下載與安裝

要了解一個軟體或者學習一個技術,第一步就是安裝,只有安裝好了,我們才可以對其進行練習和使用,最終達到掌握的目的。

Nginx 是一個開源的軟體,我們可以從官網上下載其最新的版本進行安裝和使用。

Nginx 的下載

官網:http://nginx.org/en/download.html

我們下載 nginx-1.14.1 版本,下載的是 Nginx 的原始碼,C 語言寫的。

Nginx 的安裝過程

原始碼的安裝一般有三個步驟:

        ·     配置(configure)

        ·     編譯(make)

        ·     安裝(make install)

1. 在 CentOS 7 的虛擬機器根目錄下建立 /data/program 的資料夾,用來存放應用程式檔案。

2. 把下載的 nginx-1.14.1.tar.gz 檔案上傳到 /data/program 的資料夾下。

3. 解壓 nginx-1.14.1.tar.gz 檔案。

4. 在 /data/program 目錄下建立 nginx 資料夾把 Nginx 軟體安裝到該目錄下,便於管理。

5. 對 Nginx 進行安裝前的配置檢查。

 

6. 在配置檢查這一步,可能會遇到一些缺少依賴庫的問題,按照提示用 yum 命令進行安裝即可。

7. 依賴安裝後,再一次執行命令對 Nginx 進行安裝前的配置檢查,不通過則繼續 yum 安裝依賴,直到配置檢查通過。

8. 配置好之後,進行編譯和安裝。

9. 進入 nginx 目錄下,出現 conf、html、logs、sbin 目錄,則說明安裝完成。

Nginx 的啟動和停止

Nginx 的啟動

到 /data/program/nginx/sbin 目錄下執行 ./nginx

檢視效果

訪問到下圖的介面,說明 Nginx 已經生效。

Nginx 的停止

到 /data/program/nginx/sbin 目錄下執行 ./nginx -s stop

 


四、Nginx 的配置檔案介紹

Nginx 的配置檔案是 nginx.conf,它在 /data/program/nginx/conf 目錄下。

nginx.conf 介紹

nginx.conf 配置檔案裡有 3 個部分,分別是:

        ·     全域性塊

        ·     events 塊

        ·     http 塊

在 http 塊中又包含 http 全域性塊、多個 server 塊;每個 server 塊中又包含 server 全域性塊和多個 location 塊。

   1.全域性塊是配置檔案從開始到 events 塊之間的內容,主要有 worker_processes,它表示工作程序數,一般設定為伺服器 CPU 的核數。

   2.events 塊主要有 worker_connections,它表示 Nginx 伺服器與使用者的網路連線數,Nginx 支援的網路連線數就是 worker_processes 配置數字乘 以 worker_connections 配置數字。假如 worker_processes = 4,worker_connections = 1024,那麼該 Nginx 伺服器支援的連線數就是 4 * 1024 = 4096 個。

   3.http 塊是 Nginx 伺服器配置中的重要組成部分,反向代理,負載均衡,動靜分離等多數功能都在這裡配置。

   4.server 塊裡進行虛擬主機的配置,有 3 種配置,分別是基於 IP、基於埠號、基於域名的虛擬主機。

   5.location 塊在整個 Nginx 配置文件中起著非常重要的作用,很多功能的實現需要在 location 塊種進行配置。

location 使用介紹

配置語法介紹

location 的語法結構

其中,uri 是待匹配的請求字串,可以是標準 uri(不含正則表示式的 uri),也可以是正則 uri(使用正則表示式的 uri);方括號裡的部分是可選項,用來表示請求字串與 uri 的匹配方式。

配置規則介紹

在沒有可選項的情況下,指的就是通用匹配。

        1.Nginx 伺服器首先在 server 塊的多個 location 中搜索是否有標準 uri 和請求字串匹配,如果有多個可以匹配,就記錄匹配度最高的一個。

        2.然後,伺服器再用 location 塊中的正則 uri 和請求字串匹配,當第一個正則 uri 匹配成功,結束搜尋,並使用這個 location 塊處理該請求;

        ..如果正則匹配全部失敗,就使用剛才記錄的匹配度最高的 location 塊處理該請求。

使用 “=” 修飾 uri,指的是精準匹配:

        ·   如果匹配成功,就停止繼續向下搜尋,立即用匹配到的 location 塊處理該請求。

使用“^~”修飾 uri,指字首匹配:

        ·   要求 Nginx 伺服器找到標識 uri 和請求字串匹配度最高的 location 後,立即使用此 location 塊處理該請求,而不再使用正則 uri 匹配。

使用“~*”或者“~”修飾 uri,指正則匹配:

        ·   正則匹配會覆蓋通用匹配。

規則的優先順序

從上面的配置規則可以看出,精準匹配的優先順序最高,字首匹配的優先順序第二,正則匹配第三。

nginx.conf 檔案簡化版配置示例

至此 Nginx 的基礎介紹完畢,下面將進行例項演示。

五、例項演示環境介紹(CentOS + Nginx + Tomcat)

作業系統是 CentOS 7.5;

Nginx 伺服器版本是 nginx-1.14.1,IP=192.168.1.8;

Tomcat 伺服器版本是 apache-tomcat-8.5.35,兩臺 Tomcat 伺服器 Tomcat1 的 IP=192.168.1.9,Tomcat2 的 IP=192.168.1.10。

架構圖如下:

六、Nginx 的反向代理演示

Nginx 預設自帶 proxy_pass 指令,通過在 nginx.conf 配置檔案中設定 proxy_pass 的引數就可以實現反向代理。

proxy_pass 既可以是域名,也可以是 IP 地址,還可以指定埠。

示例說明

使用者在瀏覽器輸入 http://192.168.1.8 本來訪問到的是 Nginx 的首頁,我們希望 Nginx 代理 Tomcat1 伺服器,使用者訪問 http://192.168.1.8 開啟 Tomcat1 伺服器的首頁。

nginx.conf 配置

在 http 塊的 server 塊的 location 塊寫入如下程式碼:

 

啟動 Tomcat1 伺服器的 Tomcat,然後重啟 Nginx,瀏覽器訪問 http://192.168.1.8。

重啟 Nginx,在 /data/program/nginx 目錄下輸入以下命令:

 

啟動 Tomcat1 伺服器的 Tomcat,在 /data/program/tomcat8/bin 目錄下輸入以下命令:

瀏覽器輸入 http://192.168.1.8,看訪問結果如下:

說明反向代理設定成功。

七、Nginx 的負載均衡演示

準備篇

為了進行負載均衡的演示,Tomcat 伺服器的 /data/program/tomcat8/webapps/ROOT 目錄下,我們把原始 index.jsp 備份,修改其內容,以便區分兩臺 Tomcat 伺服器。

Tomcat1 的 index.jsp 的上部增加以下程式碼:

如下圖:

Tomcat2 不用修改,就用原始的 Tomcat 首頁,這樣就能區分出使用者實際訪問到的是哪臺 Tomcat 伺服器了。

我們訪問 Tomcat1 伺服器的地址 http://192.168.1.9:8080。

接下來,我們啟動 Tomcat2 伺服器的 Tomcat,訪問 Tomcat2 伺服器的地址 http://192.168.1.10:8080。

nginx.conf 原始配置引用外部配置檔案

為了修改方便,我們在 nginx.conf 的 http 塊裡通過 include 指令引入外部的配置檔案,這樣可以把不同功能的配置放到不同的配置檔案中,避免每次都去修改原始 nginx.conf 配置。

我們在 /data/program/nginx/conf 目錄下新建 userconf 資料夾,在 userconf 資料夾下建立 proxy.conf 檔案,用於寫 Nginx 的配置資訊。

修改 nginx.conf 配置,在 http 塊裡寫入如下程式碼,表示引用 userconf 資料夾下的所有 conf 檔案。

同時刪除剛才配置的反向代理程式碼。

如下圖:

負載均衡篇

負載均衡的原理是用一些策略把網路的訪問平衡地分配到叢集的各個節點上,使得大量併發訪問可以均衡到後端伺服器的叢集處理,提高網站的效能。

Nginx 的負載均衡是通過 upstream 模組實現的,它提供了一些排程演算法來實現客戶端 IP 到服務端的負載均衡。

Nginx 預設輪詢演算法,當伺服器宕機後,自動遮蔽,不再往宕機的 IP 分發使用者請求。

IP 雜湊演算法,根據客戶端的請求 IP 進行雜湊,一個 IP 訪問到了後端伺服器,以後個使用者 IP 每次都會請求到第一次訪問的後端伺服器,這種方式可以解決 session 共享的問題。

示例說明

使用者在瀏覽器輸入 http://192.168.1.8 本來訪問到的是 Tomcat1 伺服器,我們加了一臺 Tomcat2 的伺服器,想達到使用者訪問 http://192.168.1.8 後,負載均衡到 2 臺 Tomcat 伺服器上,既能開啟 Tomcat1 伺服器的首頁,也能開啟 Tomcat2 伺服器的首頁。

在 proxy.conf 配置檔案里加入負載均衡的程式碼

重啟 Nginx 後,訪問 http://192.168.1.8。

第一次訪問到了 Tomcat1,第二次訪問到了 Tomcat2,說明負載均衡的功能實現了。

八、Nginx 的動靜分離演示

        ·   靜態資源:HTML、CSS、JS、圖片、XML、MP4 等(不需要依賴 Tomcat 容器),可參考 /data/program/nginx/conf/mime.types 檔案裡的內容。

        ·   動態資源:JSP、Servlet(需要 Tomcat 容器)。

動靜分離,就是將 HTML、CSS、JS 等靜態資源和 JSP 等動態資源分開部署,從而達到提高伺服器響應速度,提高伺服器效能的目的。

示例說明

依然以 Tomcat1 和 Tomcat2 伺服器的首頁為例:

        1.首先需要把靜態資源從 Tomcat 伺服器刪掉,分別訪問 2 臺 Tomcat 伺服器,發現網站的樣式和圖片沒有了;

        2.通過代理伺服器訪問,也是一樣的,樣式和圖片沒有了;

        3.最後,我們把 Tomcat 的靜態資源放到 Nginx 的根目錄的 static_resource 資料夾下,在 location 塊裡用正則匹配,做好動靜分離的配置,重啟 Nginx 服務後,通過代理伺服器 IP 訪問,發現 Tomcat 首頁可以正常訪問。

準備階段

1. 我們在 Tomcat1 伺服器 /data/program/tomcat8/webapps/ROOT 目錄下新建 static_resource,把靜態資源拷貝到 stataic_resource 資料夾下,這樣相當於靜態資源刪掉了,如下圖。

2. 我們在 Tomcat2 伺服器 /data/program/tomcat8/webapps/ROOT 目錄下新建 static_resource,把靜態資源拷貝到 stataic_resource 資料夾下,這樣相當於靜態資源刪掉了,如下圖。

3. 訪問 Tomcat1 伺服器,顯示如下:

)

4. 訪問 Tomcat2 伺服器,顯示如下:

5. 通過 Nginx 代理訪問,顯示如下:

說明靜態資源訪問不到了。

Nginx 動靜分離配置

1. 在 Nginx 的 /data/program/nginx 目錄下新建 static_resource 資料夾,裡面放 Tomcat 伺服器的靜態資源,如下圖:

2. 修改 Nginx 的 /data/program/nginx/conf/userconf/proxy.conf 檔案並儲存,用正則來匹配 JS、CSS、圖片等靜態資源,不區分大小寫。

如下圖:

3. 重啟 Nginx 服務,通過 Nginx 代理訪問,如下:

4. 兩臺 Tomcat 伺服器的樣式和圖片能正常顯示,說明 Nginx 的動靜分離已經配置成功。

動靜分離的優勢

        ·   靜態檔案從後端伺服器分離出來單獨部署,可以減輕後端伺服器的訪問壓力,同時 Nginx 是一個高效能的靜態 Web 伺服器,用它可以做靜態資源伺服器。

        ·   靜態檔案一般變化不大,動靜分離之後,可以對靜態檔案進行緩衝,以提高網站的效能。

上面的 location 塊配置中 [expires 1d;] 就是表示緩衝一天的時間。

九、Nginx 解決跨域訪問問題演示

什麼是跨域訪問

如果 2 個伺服器節點的協議、域名、埠有一個不同,那麼這 2 臺伺服器之間互相訪問就會出現跨域訪問的問題,跨域限制的根本原因是瀏覽器的限制,瀏覽器為了安全從而限制跨域訪問。

跨域示例說明

驗證一

假設 Tomcat2 伺服器部署了一個 hello.json 檔案,裡面是一個 JSON 格式的資料,用它來模擬跨域訪問問題。

hello.json 內容如下:

Tomcat1 伺服器上的 index.jsp 通過一段 JS 程式碼要獲取到 Tomcat2 伺服器上的 hello.json 內容,並通過 alert 輸出 key=hello 的值 world。

在 Tomcat1 伺服器的 ROOT 下上傳 jquery-2.1.1.min.js 檔案,在 index.jsp 檔案的 head 中增加如下程式碼:

如下圖:

通過瀏覽器輸入 http://192.168.1.9:8080,提示“Failed to load http://192.168.1.10:8080/hello.json: No 'Access-Control-Allow-Origin' ”,說明出現了跨域訪問問題。

驗證二

如果我們在 Tomcat1 的 index.jsp 裡通過 Nginx 代理獲取 Tomcat2 伺服器的 hello.json 檔案,是否可行呢?

1. 修改 /data/program/tomcat8/webapps/ROOT 目錄下的 index.jsp 檔案,把 IP 地址改為 Nginx 代理的地址:

2. 修改 /data/program/nginx/conf/userconf 目錄下的 proxy.conf 配置,註釋掉對 192.168.1.9:8080 的反向代理,為了演示,讓其只代理 192.168.1.10:8080。

3. 重啟 Nginx 伺服器,通過瀏覽器輸入 http://192.168.1.9:8080,提示“Failed to load http://192.168.1.8/hello.json: No 'Access-Control-Allow-Origin'”,說明依然存在跨域訪問問題。

驗證三:通過 Nginx 的配置解決以上出現的跨域問題

再次修改 /data/program/nginx/conf/userconf 目錄下的 proxy.conf 配置,通過 add_header 設定解決跨域訪問問題。

如下圖:

儲存配置,並重啟 Nginx 伺服器。

通過瀏覽器輸入 http://192.168.1.9:8080,可以彈出 world 的值,如下:

因此,說明通過 Nginx 的配置,我們解決了上面的跨域訪問問題,可以正常獲取到 Tomcat2 伺服器上的 JSON 資源。

上面的網頁沒有樣式,是因為之前我們把 Tomcat 裡面的靜態資源挪走導致的。

十、Nginx 的防盜鏈配置演示

防盜鏈就是指別人的網站不可以訪問我們自己網站的JS、CSS、圖片等靜態資源。

第一,圖片有版權,我們不希望別人引用;

第二,別人引用了我們的地址,消耗的是我們網站的流量,因為很多網站買的是雲服務,是按流量收費的,如果不加防盜鏈的限制,會提升我們的運營成本,所以一個網站最好要考慮防盜鏈配置。

1. 為了做防盜鏈的演示,修改 Tomcat1 的 /data/program/tomcat8/webapps/ROOT 目錄下的 index.jsp,把 Tomcat 圖片改成訪問 Nginx 代理伺服器裡的靜態圖片資源,程式碼如下:

如圖:

2. 訪問 Tomcat1 的地址 http://192.168.1.9:8080,如果沒有防盜鏈配置,則可以訪問到 Nginx 伺服器上的靜態 Tomcat 圖示,如下:

3. 修改 /data/program/nginx/conf/userconf 目錄下的 proxy.conf 配置,通過 valid_referers 設定解決防盜鏈問問題,讓除了 192.168.1.8 IP 以外的伺服器不能訪問 Nginx 伺服器上的靜態資源。

如下圖:

4. 儲存配置,重啟 Nginx 伺服器,再次訪問 Tomcat1 的地址 http://192.168.1.9:8080,因為上面設定了防盜鏈配置,因此不能訪問到 Nginx 伺服器上的靜態 Tomcat 圖示,如下:

以上就是防盜鏈產生了作用,導致 192.168.1.9 伺服器部署的應用不可以訪問 192.168.1.8 的圖片。

加入群(Java填坑之路)789337293 可以免費獲取到【Java核心知識點合集寶典】文件,Java208道面試題(含答案)喔 ! 粉絲群直通車:https://jq.qq.com/?_wv=1027&k=5o02eBd 點選連結可直接