Nginx部署負載均衡服務全解析

👉 這是一個或許對你有用的社群
🐱 一對一交流/面試小冊/簡歷最佳化/求職解惑,歡迎加入芋道快速開發平臺知識星球。下面是星球提供的部分資料:
👉這是一個或許對你有用的開源專案
國產 Star 破 10w+ 的開源專案,前端包括管理後臺 + 微信小程式,後端支援單體和微服務架構。
功能涵蓋 RBAC 許可權、SaaS 多租戶、資料許可權、商城、支付、工作流、大屏報表、微信公眾號、ERPCRMAI 大模型等等功能:
  • Boot 多模組架構:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 微服務架構:https://gitee.com/zhijiantianya/yudao-cloud
  • 影片教程:https://doc.iocoder.cn
【國內首批】支援 JDK 17/21 + SpringBoot 3.3、JDK 8/11 + Spring Boot 2.7 雙版本 

關於 Nginx 的配置,松哥之前寫過好幾篇文章和小夥伴們分享了,不過大部分都是基於全域性視角去配置的,今天我們就單純來聊一聊用 Nginx 做負載均衡的配置。

一 什麼是負載均衡

負載均衡(Load Balancing)是一種計算機網路技術,用於將網路流量或請求分發到多個伺服器上,以最佳化資源使用、最大化吞吐量、最小化響應時間,並避免任何單一點過載。負載均衡的目的是確保我們的 Web 應用的高可用性和可靠性,同時提高使用者體驗。
一般來說,我們可能會在如下場景中用到負載均衡:
  1. 伺服器負載均衡:在多個伺服器之間分配網路流量,以防止任何單個伺服器因請求過多而效能下降。
  2. 資料中心負載均衡:在資料中心的不同位置或不同資料中心之間分配流量,以最佳化資源利用和提高可靠性。
  3. 雲服務負載均衡:在雲環境中,負載均衡可以跨多個虛擬機器或容器服務分配流量。
雖然我們平時做負載均衡基本上都是 Nginx,但是考慮到文章內容的完整性,松哥還是和大家說一說負載均衡這事可以在不同的網路層面實行,比如:
  • DNS 負載均衡 :透過 DNS 服務將域名解析成不同的 IP 地址,將流量分散到不同的伺服器上。
  • 硬體負載均衡 :使用專門的硬體裝置(如 F5 BIG-IP)來分配流量。
  • 軟體負載均衡 :使用軟體解決方案(如 Nginx、HAProxy)來實現負載均衡。
  • 應用層負載均衡 :在應用層(如 HTTP/HTTPS)分配請求到不同的伺服器。
  • 傳輸層負載均衡 :在傳輸層(如 TCP/UDP)分配連線到不同的伺服器。
基於 Spring Boot + MyBatis Plus + Vue & Element 實現的後臺管理系統 + 使用者小程式,支援 RBAC 動態許可權、多租戶、資料許可權、工作流、三方登入、支付、簡訊、商城等功能
  • 專案地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 影片教程:https://doc.iocoder.cn/video/

二 常見負載均衡演算法

無論你使用哪種工具,在哪進行負載均衡,常見的負載均衡演算法主要是下面這幾種:
  • 輪詢(Round Robin) :將請求輪流分配給每臺伺服器。
  • 最少連線(Least Connections) :將請求分配給當前連線數最少的伺服器。
  • 加權輪詢(Weighted Round Robin) :根據伺服器的效能權重來分配請求。
  • 加權最少連線(Weighted Least Connections) :根據伺服器的效能權重和當前連線數來分配請求。
  • IP 雜湊(IP Hash) :根據客戶端 IP 地址的雜湊值來分配請求,以保證來自同一 IP 的請求總是被分配到同一臺伺服器上。
基於 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現的後臺管理系統 + 使用者小程式,支援 RBAC 動態許可權、多租戶、資料許可權、工作流、三方登入、支付、簡訊、商城等功能
  • 專案地址:https://github.com/YunaiV/yudao-cloud
  • 影片教程:https://doc.iocoder.cn/video/

三 Nginx 配置

3.1 輪詢(Round Robin)

輪詢是 Nginx 預設的負載均衡策略,它將客戶端的請求按順序輪流分配到後端伺服器上。如果後端伺服器宕機,Nginx 會自動將其剔除出佇列,直到該伺服器恢復正常。
舉個栗子

upstream backend {  

    server backend1.example.com;  

    server backend2.example.com;  

    server backend3.example.com;  

}  
server {  

    ...  

    location / {  

        proxy_pass http://backend;  

    }  

    ...  

}

在上面的配置中,Nginx 會將請求依次分配給 backend1、backend2 和 backend3,迴圈往復。

3.2 加權輪詢

加權輪詢策略允許你為後端伺服器分配不同的權重,權重越高的伺服器將接收更多的請求。這可以根據伺服器的硬體配置、處理能力等因素進行靈活配置。

http {  

    upstream myapp1 {  

# 定義一個名為myapp1的伺服器組  

        server backend1.example.com weight=5;  

# 新增一個伺服器,並設定權重為5  

        server backend2.example.com;  

# 新增另一個伺服器,權重預設為1  

        server backend3.example.com down;  

# 將此伺服器標記為down,不參與負載均衡  

        server backup1.example.com backup;  

# 將此伺服器作為備份伺服器  

    }  
    server {  

        listen 80;  

# 監聽80埠  

        location / {  

# 匹配所有請求  

            proxy_pass http://myapp1;  

# 將請求轉發到myapp1伺服器組  

            proxy_set_header Host 

$host

;  

# 設定請求頭中的Host欄位為原始請求的Host  

            proxy_set_header X-Real-IP 

$remote_addr

;  

# 設定請求頭中的X-Real-IP欄位為客戶端的真實IP地址  

            proxy_set_header X-Forwarded-For 

$proxy_add_x_forwarded_for

;  

# 設定請求頭中的X-Forwarded-For欄位,以記錄原始請求和代理鏈的IP地址  

            proxy_set_header X-Forwarded-Proto 

$scheme

;  

# 設定請求頭中的X-Forwarded-Proto欄位為原始請求的協議(http或https)  

        }  

    }  

}

上面的負載均衡策略是權重,除了權重之外,還有輪詢以及 ip_hash 等。

3.3 IP 雜湊(IP Hash)

IP 雜湊策略根據客戶端的 IP 地址進行雜湊運算,將相同的請求分配給同一個後端伺服器。
這種策略適用於需要保持會話(Session)的場景,因為同一個客戶端的請求會被髮送到同一個伺服器,從而避免了會話資訊的丟失。

upstream backend {  

    ip_hash;  

    server backend1.example.com;  

    server backend2.example.com;  

    server backend3.example.com;  

}  
server {  

    ...  

    location / {  

        proxy_pass http://backend;  

    }  

    ...  

}

在上面的配置中,Nginx 會根據客戶端的 IP 地址進行雜湊運算,然後將請求分配到對應的後端伺服器。

3.4 最少連線(Least Connections)

最少連線策略將新的請求分配給當前連線數最少的後端伺服器。這種策略可以確保每個後端伺服器的負載相對均衡,避免某個伺服器過載而其他伺服器空閒的情況。
注意:Nginx 原生的 Stream 模組支援最少連線,但在 HTTP 模組中通常需要藉助第三方外掛或指令碼實現。
對於 HTTP 模組,可以透過第三方外掛如 ngx_http_upstream_fair_module 或編寫 Lua 指令碼來實現類似的功能。
但在 Stream 模組中,可以直接配置,下面是一個 Stream 中配置的例子:

upstream backend {  

    least_conn;  

    server backend1.example.com;  

    server backend2.example.com;  

    server backend3.example.com;  

}  
stream {  

    server {  

        listen 12345;  

        proxy_pass backend;  

    }  

}

3.5 健康檢查

在 Nginx 中配置負載均衡的健康檢查,可以透過主動健康檢查(Active Health Checks)和被動健康檢查(Passive Health Checks)兩種方式來實現。

主動健康檢查

主動健康檢查是定期向上遊伺服器傳送請求以檢查其健康狀況,如果上游伺服器未能正確響應,Nginx 將認為該伺服器不健康,並停止向其傳送流量,直到伺服器恢復健康。
配置方式如下:

http {

    upstream backend {

        server backend1.example.com;

        server backend2.example.com;

        check interval=3000 rise=2 fall=5 timeout=1000 

type

=http;

        check_http_send 

"HEAD /health HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"

;

        check_http_expect_alive http_2xx http_3xx;

    }

    server {

        location / {

            proxy_pass http://backend;

        }

    }

}

在這個配置中,Nginx 將每隔 3 秒(interval=3000)向 /health 端點發送一個 HEAD 請求。如果伺服器連續兩次返回 2xx 或 3xx 的 HTTP 狀態碼(rise=2),則認為伺服器是健康的。如果伺服器連續五次未能正確響應(fall=5),則認為伺服器不健康。

被動健康檢查

被動健康檢查基於即時流量分析,Nginx 根據後端伺服器的響應來判斷其健康狀況。如果伺服器返回特定的錯誤狀態碼,Nginx 將認為該伺服器不健康,並在一段時間內不再將請求傳送到該伺服器。
配置方式如下:

http {

    upstream backend {

        server backend1.example.com;

        server backend2.example.com max_fails=2 fail_timeout=30s;

    }

    server {

        listen 80;

        location / {

            proxy_pass backend;

            proxy_next_upstream error timeout http_500 http_502 http_503 http_504;

        }

    }

}

在這個配置中,如果後端伺服器在 30 秒內連續兩次(max_fails=2)未能正確響應,它將被臨時從伺服器池中移除。proxy_next_upstream 指令指定了哪些錯誤應該觸發使用不同的伺服器進行重試。
好啦,Nginx 負載均衡一般來說配置這些就夠啦~

一 什麼是負載均衡

負載均衡(Load Balancing)是一種計算機網路技術,用於將網路流量或請求分發到多個伺服器上,以最佳化資源使用、最大化吞吐量、最小化響應時間,並避免任何單一點過載。負載均衡的目的是確保我們的 Web 應用的高可用性和可靠性,同時提高使用者體驗。
一般來說,我們可能會在如下場景中用到負載均衡:
  1. 伺服器負載均衡:在多個伺服器之間分配網路流量,以防止任何單個伺服器因請求過多而效能下降。
  2. 資料中心負載均衡:在資料中心的不同位置或不同資料中心之間分配流量,以最佳化資源利用和提高可靠性。
  3. 雲服務負載均衡:在雲環境中,負載均衡可以跨多個虛擬機器或容器服務分配流量。
雖然我們平時做負載均衡基本上都是 Nginx,但是考慮到文章內容的完整性,松哥還是和大家說一說負載均衡這事可以在不同的網路層面實行,比如:
  • DNS 負載均衡 :透過 DNS 服務將域名解析成不同的 IP 地址,將流量分散到不同的伺服器上。
  • 硬體負載均衡 :使用專門的硬體裝置(如 F5 BIG-IP)來分配流量。
  • 軟體負載均衡 :使用軟體解決方案(如 Nginx、HAProxy)來實現負載均衡。
  • 應用層負載均衡 :在應用層(如 HTTP/HTTPS)分配請求到不同的伺服器。
  • 傳輸層負載均衡 :在傳輸層(如 TCP/UDP)分配連線到不同的伺服器。

二 常見負載均衡演算法

無論你使用哪種工具,在哪進行負載均衡,常見的負載均衡演算法主要是下面這幾種:
  • 輪詢(Round Robin) :將請求輪流分配給每臺伺服器。
  • 最少連線(Least Connections) :將請求分配給當前連線數最少的伺服器。
  • 加權輪詢(Weighted Round Robin) :根據伺服器的效能權重來分配請求。
  • 加權最少連線(Weighted Least Connections) :根據伺服器的效能權重和當前連線數來分配請求。
  • IP 雜湊(IP Hash) :根據客戶端 IP 地址的雜湊值來分配請求,以保證來自同一 IP 的請求總是被分配到同一臺伺服器上。

三 Nginx 配置

3.1 輪詢(Round Robin)

輪詢是 Nginx 預設的負載均衡策略,它將客戶端的請求按順序輪流分配到後端伺服器上。如果後端伺服器宕機,Nginx 會自動將其剔除出佇列,直到該伺服器恢復正常。
舉個栗子

upstream backend {  

    server backend1.example.com;  

    server backend2.example.com;  

    server backend3.example.com;  

}  
server {  

    ...  

    location / {  

        proxy_pass http://backend;  

    }  

    ...  

}

在上面的配置中,Nginx 會將請求依次分配給 backend1、backend2 和 backend3,迴圈往復。

3.2 加權輪詢

加權輪詢策略允許你為後端伺服器分配不同的權重,權重越高的伺服器將接收更多的請求。這可以根據伺服器的硬體配置、處理能力等因素進行靈活配置。

http {  

    upstream myapp1 {  

# 定義一個名為myapp1的伺服器組  

        server backend1.example.com weight=5;  

# 新增一個伺服器,並設定權重為5  

        server backend2.example.com;  

# 新增另一個伺服器,權重預設為1  

        server backend3.example.com down;  

# 將此伺服器標記為down,不參與負載均衡  

        server backup1.example.com backup;  

# 將此伺服器作為備份伺服器  

    }  
    server {  

        listen 80;  

# 監聽80埠  

        location / {  

# 匹配所有請求  

            proxy_pass http://myapp1;  

# 將請求轉發到myapp1伺服器組  

            proxy_set_header Host 

$host

;  

# 設定請求頭中的Host欄位為原始請求的Host  

            proxy_set_header X-Real-IP 

$remote_addr

;  

# 設定請求頭中的X-Real-IP欄位為客戶端的真實IP地址  

            proxy_set_header X-Forwarded-For 

$proxy_add_x_forwarded_for

;  

# 設定請求頭中的X-Forwarded-For欄位,以記錄原始請求和代理鏈的IP地址  

            proxy_set_header X-Forwarded-Proto 

$scheme

;  

# 設定請求頭中的X-Forwarded-Proto欄位為原始請求的協議(http或https)  

        }  

    }  

}

上面的負載均衡策略是權重,除了權重之外,還有輪詢以及 ip_hash 等。

3.3 IP 雜湊(IP Hash)

IP 雜湊策略根據客戶端的 IP 地址進行雜湊運算,將相同的請求分配給同一個後端伺服器。
這種策略適用於需要保持會話(Session)的場景,因為同一個客戶端的請求會被髮送到同一個伺服器,從而避免了會話資訊的丟失。

upstream backend {  

    ip_hash;  

    server backend1.example.com;  

    server backend2.example.com;  

    server backend3.example.com;  

}  
server {  

    ...  

    location / {  

        proxy_pass http://backend;  

    }  

    ...  

}

在上面的配置中,Nginx 會根據客戶端的 IP 地址進行雜湊運算,然後將請求分配到對應的後端伺服器。

3.4 最少連線(Least Connections)

最少連線策略將新的請求分配給當前連線數最少的後端伺服器。這種策略可以確保每個後端伺服器的負載相對均衡,避免某個伺服器過載而其他伺服器空閒的情況。
注意:Nginx 原生的 Stream 模組支援最少連線,但在 HTTP 模組中通常需要藉助第三方外掛或指令碼實現。
對於 HTTP 模組,可以透過第三方外掛如 ngx_http_upstream_fair_module 或編寫 Lua 指令碼來實現類似的功能。
但在 Stream 模組中,可以直接配置,下面是一個 Stream 中配置的例子:

upstream backend {  

    least_conn;  

    server backend1.example.com;  

    server backend2.example.com;  

    server backend3.example.com;  

}  
stream {  

    server {  

        listen 12345;  

        proxy_pass backend;  

    }  

}

3.5 健康檢查

在 Nginx 中配置負載均衡的健康檢查,可以透過主動健康檢查(Active Health Checks)和被動健康檢查(Passive Health Checks)兩種方式來實現。

主動健康檢查

主動健康檢查是定期向上遊伺服器傳送請求以檢查其健康狀況,如果上游伺服器未能正確響應,Nginx 將認為該伺服器不健康,並停止向其傳送流量,直到伺服器恢復健康。
配置方式如下:

http {

    upstream backend {

        server backend1.example.com;

        server backend2.example.com;

        check interval=3000 rise=2 fall=5 timeout=1000 

type

=http;

        check_http_send 

"HEAD /health HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n"

;

        check_http_expect_alive http_2xx http_3xx;

    }

    server {

        location / {

            proxy_pass http://backend;

        }

    }

}

在這個配置中,Nginx 將每隔 3 秒(interval=3000)向 /health 端點發送一個 HEAD 請求。如果伺服器連續兩次返回 2xx 或 3xx 的 HTTP 狀態碼(rise=2),則認為伺服器是健康的。如果伺服器連續五次未能正確響應(fall=5),則認為伺服器不健康。

被動健康檢查

被動健康檢查基於即時流量分析,Nginx 根據後端伺服器的響應來判斷其健康狀況。如果伺服器返回特定的錯誤狀態碼,Nginx 將認為該伺服器不健康,並在一段時間內不再將請求傳送到該伺服器。
配置方式如下:

http {

    upstream backend {

        server backend1.example.com;

        server backend2.example.com max_fails=2 fail_timeout=30s;

    }

    server {

        listen 80;

        location / {

            proxy_pass backend;

            proxy_next_upstream error timeout http_500 http_502 http_503 http_504;

        }

    }

}

在這個配置中,如果後端伺服器在 30 秒內連續兩次(max_fails=2)未能正確響應,它將被臨時從伺服器池中移除。proxy_next_upstream 指令指定了哪些錯誤應該觸發使用不同的伺服器進行重試。
好啦,Nginx 負載均衡一般來說配置這些就夠啦~

歡迎加入我的知識星球,全面提升技術能力。
👉 加入方式,長按”或“掃描”下方二維碼噢
星球的內容包括:專案實戰、面試招聘、原始碼解析、學習路線。
文章有幫助的話,在看,轉發吧。
謝謝支援喲 (*^__^*)

相關文章