天天看點

nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):Nginx...

上一個章節,我們學習了負載均衡的理論知識,那麼是不是把應用部署多套,前面挂一個負載均衡的軟體或硬體就可以應對高并發了?其實還有很多問題需要考慮。比如:

1. 當一台伺服器挂掉,請求如何轉發到其他正常的伺服器上?
2. 挂掉的伺服器,怎麼才能不再通路?
3. 如何保證負載均衡的高可用性?

等等等等...

讓我們帶着這些問題,實戰學習一下 Nginx 的配置和使用。
           

1. 前置概念

在正式介紹 Nginx 之前,首先讓我們先了解一下概念。

1. 中間件

幹 IT 太累了,我準備辭職開了個燒烤攤,賣羊肉串;

賣羊肉串首先就得有羊肉,于是我就聯系了很多養殖場,我又是一個比較負責任的人,為了保證羊肉的品質,我就去考察了一家又一家養殖場,同時我也是個“小氣”的人,是以我考察過程中,和對方談判、比價,最終選了一個養殖場作為我的羊肉供應商,為我提供羊肉。

經營了一陣子,這個養殖場提供的羊肉品質沒有以前好了,那麼我就重新考察、談判、比價,如此反複,我投入了大量的時間和精力。

于是我找到了一個信得過的代理公司,約定要羊肉的品質和數量,談好價錢,以後我隻找代理商拿貨,具體代理商找的哪家養殖場我不去過問,甚至代理商可以送貨上門。

在這個例子裡面,賣燒烤就是業務,我的燒烤攤是業務端,養殖場是底層,而

這個信得過的代理公司,就是中間件。 2. 正向代理和反向代理

正向代理:我住在北京,但是想回老家買套房,但是我沒辦法親自回老家考察,于是我就派我的管家回老家考察;管家就是正向代理伺服器;正向代理伺服器代表了用戶端,在正向代理的過程中,服務端隻和代理伺服器打交道(房東隻和我的管家談),并不知道真正的用戶端是誰。

nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):Nginx...

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

nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):Nginx...

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

nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):Nginx...

2. Nginx 的概念

了解完上面的幾個概念,那麼 Nginx 的概念了解起來就簡單很多了:

Nginx 就是一個開源的、高性能的、可靠的 Http 中間件;

它經常被用作 Http 代理、反向代理、負載均衡等等,當然它也能做正向代理,但是實際很少有這麼用的。

3. 最簡單的 Nginx 使用示例

本章節項目的代碼:chapter3

Step 1. 部署多套環境

我們将章節 1 中的項目 chapter1 複制出來一份,改名為 chapter3,表示是第 3 章節的項目,同時修改:

1. pom.xml 中的 artifactId 修改為 chapter32. 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.2conf 目錄下,用文本編輯器打開 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
           
nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):Nginx...

Step 5. 測試 Nginx

讓我們測試一下 Nginx 是否配置并啟動成功,打開浏覽器輸入:

http://127.0.0.1/queryAdmin
           

注意這裡并沒有加端口号,是因為 url 中沒有端口号的時候表示端口号為 80,而我們 Nginx 的配置檔案中,監聽的正是 80 端口 (listen 80);我們可以在浏覽器中看到服務傳回的結果:

User : Admin
           

這就說明 Nginx 已經轉發了我們的請求到了服務端,并正确傳回,那麼負載均衡是如何展現的呢?讓我們多重新整理幾次浏覽器,然後看看背景日志:

nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):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 一直沒有改變。

nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):Nginx...

3. 權重輪詢法

使用 weight 關鍵字,設定每台伺服器的權重;

upstream myserver{
   server 127.0.0.1:8088 weight=1;  # 20% 請求會發給8088
   server 127.0.0.1:8089 weight=4;
}
           
nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):Nginx...

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 端口服務的背景日志,列印出來日志,調用端接收到了傳回,這說明:

  1. Nginx 預設有失敗重試機制;
  2. 預設的逾時時間為 60s 。
nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):Nginx...

這裡的逾時時間是可以修改的,需要在 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 逾時重試,那麼可能會造成重複處理。

nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):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 同樣也需要部署多台,架構大概是這個樣子的:

nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):Nginx...

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

nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):Nginx...
nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):Nginx...

5.4 其他

除了以上的常見功能,強大的 Nginx 還可以:

  1. 限制 IP 通路頻率和帶寬占用;
  2. 緩存靜态資源;
  3. 檔案壓縮;
  4. TCP 負載;
  5. 防盜鍊;
  6. 等等等等...

總結

nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):Nginx...

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

nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):Nginx...
編輯不易,希望看到的小夥伴多多轉發,收藏,給小編一個 關注!感謝您的閱讀,下面小編給大家準備了一份(馬士兵大佬的視訊,面試資料技術文檔)進大廠必備,免費送給大家!
nginx 代理到其他端口_「從單體架構到分布式架構」請求增多,單點變叢集(2):Nginx...
如果你想成為一名優秀的 Java 架構師,那麼這份手冊上的内容幾乎是必須要掌握的。如果你想擷取這份學習資料的小夥伴,關注小編,轉發,收藏文章,私信[高并發]即可獲得擷取方式!