上一個章節,我們學習了負載均衡的理論知識,那么是不是把應用部署多套,前面掛一個負載均衡的軟體或硬體就可以應對高并發了?其實還有很多問題需要考慮,比如:
1. 當一臺服務器掛掉,請求如何轉發到其他正常的服務器上?
2. 掛掉的服務器,怎么才能不再訪問?
3. 如何保證負載均衡的高可用性?
等等等等...
讓我們帶著這些問題,實戰學習一下 Nginx 的配置和使用,
1. 前置概念
在正式介紹 Nginx 之前,首先讓我們先了解一下概念,
1. 中間件
干 IT 太累了,我準備辭職開了個燒烤攤,賣羊肉串;
賣羊肉串首先就得有羊肉,于是我就聯系了很多養殖場,我又是一個比較負責任的人,為了保證羊肉的質量,我就去考察了一家又一家養殖場,同時我也是個“小氣”的人,所以我考察程序中,和對方談判、比價,最終選了一個養殖場作為我的羊肉供應商,為我提供羊肉,
經營了一陣子,這個養殖場提供的羊肉質量沒有以前好了,那么我就重新考察、談判、比價,如此反復,我投入了大量的時間和精力,
于是我找到了一個信得過的代理公司,約定要羊肉的質量和數量,談好價錢,以后我只找代理商拿貨,具體代理商找的哪家養殖場我不去過問,甚至代理商可以送貨上門,
在這個例子里面,賣燒烤就是業務,我的燒烤攤是業務端,養殖場是底層,而 這個信得過的代理公司,就是中間件,
2. 正向代理和反向代理
正向代理:我住在北京,但是想回老家買套房,但是我沒辦法親自回老家考察,于是我就派我的管家回老家考察;管家就是正向代理服務器;正向代理服務器代表了客戶端,在正向代理的程序中,服務端只和代理服務器打交道(房東只和我的管家談),并不知道真正的客戶端是誰,

反向代理:我住在北京,但是想回老家買套房,但是我沒辦法親自回老家考察,于是我打個電話聯系了老家的房屋中介去辦這件事兒;房屋中介就是反向代理;這里的反向代理,代表的是房東,在反向代理的程序中,客戶端只和反向代理服務器打交道,并不知道真正的服務端是誰,

當然,我的管家也可以聯系我老家的房屋中介,那么架構圖就會變成:

2. Nginx 的概念
了解完上面的幾個概念,那么 Nginx 的概念理解起來就簡單很多了:
Nginx 就是一個開源的、高性能的、可靠的 Http 中間件; 它經常被用作 Http 代理、反向代理、負載均衡等等,當然它也能做正向代理,但是實際很少有這么用的,
3. 最簡單的 Nginx 使用示例
本章節專案的代碼:chapter3
Step 1. 部署多套環境
我們將章節 1 中的專案 chapter1 復制出來一份,改名為 chapter3,表示是第 3 章節的專案,同時修改:
1. pom.xml 中的 artifactId 修改為 chapter3
2. application.yml 中的 server.port 修改成 8089
這樣我們分別啟動 chapter1 和 chapter3,這樣就相當于把相同的專案部署了兩套,埠分別是 8088 和 8089 ,
Step 2. 下載 Nginx
我們可以在 Nginx 的官網 下載我們所需的版本,因為我使用 windows 環境開發,所以我在這里就選擇了 nginx/Windows-1.14.2 這個版本,
下載完成解壓縮,不需要額外的安裝,可以直接使用,
Step 3. 配置 Nginx
進入 nginx-1.14.2\conf 目錄下,用文本編輯器打開 nginx.conf,對組態檔進行如下修改:
1. 在 http 中增加 upstream,并配置兩臺環境的地址;
2. 在 http.server.location 中增加 proxy_pass 的配置;
http {
...
#增加 upstream 的配置,其中 myserver 是自己起的名字
upstream myserver{
server 127.0.0.1:8088; #有幾套環境,就配置幾條
server 127.0.0.1:8089;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
proxy_pass http://myserver; #增加,其中 http://myserver 的 myserver 要和上文對應
}
}
}
...
}
完整組態檔請參考:nginx.conf
Step 4. 啟動 Nginx
我們可以直接雙擊 nginx-1.14.2 目錄下的 nginx.exe 啟動;也可以通過 cmd 命令打開控制臺,進入 nginx-1.14.2 目錄執行如下命令啟動 Nginx:
start nginx //啟動 Nginx ;啟動后可能一閃而過,我們可以看一下任務管理器是否有名字叫做 nginx.exe 的行程
nginx.exe -s stop //停止 Nginx
nginx.exe -s quit //停止 Nginx

Step 5. 測驗 Nginx
讓我們測驗一下 Nginx 是否配置并啟動成功,打開瀏覽器輸入:
http://127.0.0.1/queryAdmin
注意這里并沒有加埠號,是因為 url 中沒有埠號的時候表示埠號為 80,而我們 Nginx 的組態檔中,監聽的正是 80 埠 (listen 80);我們可以在瀏覽器中看到服務回傳的結果:
User : Admin
這就說明 Nginx 已經轉發了我們的請求到了服務端,并正確回傳,那么負載均衡是如何體現的呢?讓我們多重繪幾次瀏覽器,然后看看后臺日志:

我前后一共呼叫了 5 次服務,可以看到兩個服務端分別接收到了 2 次和 3 次請求,負載均衡達到了效果,
4. Nginx 常見的路由策略
1. 輪詢法
最簡單的輪詢法,多余的配置不需要增加,
upstream myserver{
server 127.0.0.1:8088; # 有幾套環境,就配置幾條
server 127.0.0.1:8089;
}
2. 源地址哈希法
使用 ip_hash 關鍵字,每一個請求,都按 hash(IP) 的結果決定訪問哪臺服務器;
upstream myserver{
ip_hash; # hash(IP)
server 127.0.0.1:8088; # 有幾套環境,就配置幾條
server 127.0.0.1:8089;
}
如果我們本地測驗,多次訪問介面,可以發現請求永遠落到同一個服務上,因為本地 IP 一直沒有改變,

3. 加權輪詢法
使用 weight 關鍵字,設定每臺服務器的權重;
upstream myserver{
server 127.0.0.1:8088 weight=1; # 20% 請求會發給8088
server 127.0.0.1:8089 weight=4;
}

4. 最小連接數法
根據每個服務器節點的連接數,動態地選擇當前連接數最少的服務器轉發請求;
upstream myserver{
least_conn;
server 127.0.0.1:8088;
server 127.0.0.1:8089;
}
5. 最快回應速度法
根據每個服務器節點的回應時間(請求的往返延遲),動態地選擇當前回應速度最快的服務器轉發請求;需要額外安裝 nginx-upstream-fair 模塊,
upstream myserver{
fair; # 額外安裝 nginx-upstream-fair 模塊
server 127.0.0.1:8088;
server 127.0.0.1:8089;
}
6. URL 哈希演算法
對 URL 進行 Hash 運算,根據結果來分配請求,這樣每個 URL 都可以訪問到同一個服務端;當服務端有快取的時候,比較有效,
upstream myserver{
hash $request_uri;
server 127.0.0.1:8088; # 有幾套環境,就配置幾條
server 127.0.0.1:8089;
}
也可以安裝第三方模塊,比如我們要使用 URL 一致性哈希演算法,那么我們可以安裝 ngx_http_upstream_consistent_hash 模塊,
upstream myserver{
consistent_hash $request_uri;
server 127.0.0.1:8088;
server 127.0.0.1:8089;
}
參考資料:Upstream Consistent Hash
5. Nginx 常用功能
5.1 請求失敗重試
當一臺服務器掛掉,請求如何轉發到其他正常的服務器上?
我們可以先做個試驗,就是關閉 8089 埠的服務,只保留 8088 埠的服務,然后呼叫幾次介面,如果其中一次呼叫長時間不回傳(瀏覽器訪問狀態圖示一直在打轉),表示本次請求發送到了 8089 埠,那么讓我們等待一段時間...大約一分鐘之后,8080 埠服務的后臺日志,列印出來日志,呼叫端接收到了回傳,這說明:
- Nginx 默認有失敗重試機制;
- 默認的超時時間為 60s ,

這里的超時時間是可以修改的,需要在 http.server.location 中增加如下配置:
location / {
root html;
index index.html index.htm;
proxy_pass http://myserver;
proxy_connect_timeout 5; # 連接超時時間
proxy_send_timeout 5; # 發送資料給后端服務器的超時時間
proxy_read_timeout 5; # 后端服務器的相應時間
#proxy_next_upstream off; # 是否要關閉重試機制
}
完整組態檔請參考:設定超時重試時間5秒-nginx.conf
不過這里要注意一點,如果設定了服務器相應超時時間(比如設定了 10s ),萬一應用的業務處理時間比較慢(業務處理花費了 15s ),那么會導致 Nginx 超時重試,那么可能會造成重復處理,

5.2 后端服務器節點健康狀態檢查
如果掛掉一臺服務器,路由到這臺服務器請求每次都要等到超時時間過去,才能發起重試,如果 Nginx 不再把請求發送給掛掉的服務器,那就省事多了;
這就叫做“后端服務器節點健康狀態檢查”,
如果不安裝第三方模塊,可以做如下配置完成“后端服務器節點健康狀態檢查”:
1. 設定超時時間:
location / {
root html;
index index.html index.htm;
proxy_pass http://myserver;
proxy_connect_timeout 5; # 連接超時時間
proxy_send_timeout 5; # 發送資料給后端服務器的超時時間
proxy_read_timeout 5; # 后端服務器的相應時間
#proxy_next_upstream off; # 是否要關閉重試機制
}
2. 設定嘗試重試的次數:
upstream myserver{
server 127.0.0.1:8088 max_fails=1 fail_timeout=100s;
server 127.0.0.1:8089 max_fails=1 fail_timeout=100s;
}
其中 max_fails 表示最多失敗次數,fail_timeout 表示在一個時間段內,服務器不會再次嘗試訪問;上面的配置表示在 100s 內,只要超時失敗 1 次,就不再訪問該服務器,
完整組態檔請參考:設定超時重試時間5s-失敗1次100秒之內不再訪問-nginx.conf
除此之外,我們還可以安裝第三方模塊來實作“后端服務器節點健康狀態檢查”:
- nginx_upstream_check_module
- ngx_http_healthcheck_module
5.3 Nginx 的高可用
以為使用 Nginx ,部署了多臺應用服務器,可以保證應用服務器的高可用(掛掉一臺,還有其他服務器可以用);
但是如何保證負載均衡的高可用性?也就是萬一 Nginx 掛了怎么辦?
Nginx 同樣也需要部署多臺,架構大概是這個樣子的:

現在應用比較廣泛的是利用 keepalived 實作 Nignx 的高可用:


5.4 其他
除了以上的常見功能,強大的 Nginx 還可以:
- 限制 IP 訪問頻率和帶寬占用;
- 快取靜態資源;
- 檔案壓縮;
- TCP 負載;
- 防盜鏈;
- 等等等等...
總結

我們現在的架構已經變成了:

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/163254.html
標籤:Java
下一篇:進位計數制及其轉換
