Nginx負載均衡配置(upstream)高可用配置(Nginx+keepalived)
1 Nginx基礎(chǔ)配置
server { listen 80; listen [::]:80; server_name 192.168.110.237; add_header 'Access-Control-Allow-Origin' '*'; root /var/fetalbrain_detection/; location /admin/ { # 瀏覽器訪問路由admin進這個路徑下的index.html中 root /usr/share/nginx/html; } location /ai_images/ { # 瀏覽器訪問路由 root /usr/share/nginx/html; } location /api/ { # 前端訪問后端ip端口 proxy_pass http://192.168.110.237:8001; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
當前端訪問開頭是/api的api接口時會自動往http://192.168.110.237:8001發(fā)送請求
2 負載均衡(多個相同的后端服務)
upstream backend_servers { server 192.168.110.237:18001 weight=3; server 192.168.110.128:18001; } upstream backend_servers01 { server 192.168.110.237:18002; server 192.168.110.128:18002; } server { listen 80; listen [::]:80; server_name 192.168.110.128; add_header 'Access-Control-Allow-Origin' '*'; root /var/fetalbrain_detection/; location /admin/ { # 瀏覽器訪問admin路由 root /usr/share/nginx/html; } location /ai_images/ { # 瀏覽器訪問admin路由 root /usr/share/nginx/html; } location /user/ { # 前端訪問user后端服務的ip和端口 proxy_pass http://backend_servers; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /data/ { # 前端訪問data后端服務的ip和端口 proxy_pass http://backend_servers01; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } error_page 500 502 503 504 /50x.html; location = / { root /www; index index.html index.html; } }
upstream塊定義了一個名為backend_servers的后端服務器列表。列表中列出了兩個后端服務器 237:18001和128:18001都是同一個user服務,另外定義了一個名為backend_servers01的后端服務器列表。列表中列出了兩個后端服務器 237:18002和128:18002都是同一個data服務
可以設(shè)置權(quán)重(weight)來控制請求轉(zhuǎn)發(fā)的比例,這里server 192.168.110.237:18001 weight=3; 的權(quán)重設(shè)置為3,表示它會接收更多的請求,默認是輪詢方式請求按順序分配
當前端訪問開頭是/user的api接口時會自動往backend_servers的后端服務器列表發(fā)送請求
Nginx負載均衡算法
1. 輪詢(Round Robin):按順序?qū)⒄埱蠓职l(fā)給后端服務器(默認)。
2. IP哈希(IP Hash):根據(jù)客戶端IP地址將請求分配給同一臺后端服務器。
3. 最少連接(Least Connections):將請求分配給當前連接數(shù)最少的后端服務器。
4. 加權(quán)輪詢(Weighted Round Robin):根據(jù)服務器權(quán)重分配請求,權(quán)重越高,接收到的請求越多。
IP哈希(IP Hash): IP哈希算法根據(jù)客戶端的IP地址將請求分配給后端服務器。通過對客戶端IP地址進行哈希運算,**每個客戶端的請求都會被分配給同一臺后端服務器。**這對于需要保持會話或狀態(tài)的應用程序很有用,因為同一客戶端的請求將始終被發(fā)送到相同的服務器。
http { upstream backend_servers { ip_hash; server backend1.example.com; server backend2.example.com; } server { listen 80; server_name example.com; location / { proxy_pass http://backend_servers; } } }
最少連接(Least Connections): 最少連接算法將請求分配給當前連接數(shù)最少的后端服務器。它根據(jù)后端服務器的當前連接數(shù)動態(tài)地選擇目標服務器,以實現(xiàn)負載均衡。這樣可以使連接數(shù)更均衡地分布在后端服務器之間,從而提高性能和響應速度。
http { upstream backend_servers { least_conn; server backend1.example.com; server backend2.example.com; } server { listen 80; server_name example.com; location / { proxy_pass http://backend_servers; } } }
加權(quán)輪詢(Weighted Round Robin): 加權(quán)輪詢算法根據(jù)服務器的權(quán)重來分配請求。每個后端服務器都有一個權(quán)重值,權(quán)重越高,接收到的請求越多。通過給予不同的服務器不同的權(quán)重,可以實現(xiàn)更靈活的負載均衡策略,使請求更加均衡地分布在不同的服務器上。
http { upstream backend_servers { server backend1.example.com weight=3; server backend2.example.com weight=2; server backend3.example.com weight=1; } server { listen 80; server_name example.com; location / { proxy_pass http://backend_servers; } } }
3 keepalived
1. 高可用的基本介紹
在使用 Nginx 做反向代理或者負載均衡的時候,都是以 Nginx 為入口,如果 Nginx 宕機了,那么所有的服務都無法正常提供,影響非常嚴重。所有我們需要保證 nginx 高可用,就是配置備份機,前一個掛了,還有后一個。
為了避免負載均衡服務器宕機造成嚴重影響,就需要建立一個備份機。主服務器和備份機上都運行高可用(High Availability)監(jiān)控程序,通過傳送諸如“I am alive”這樣的信息來監(jiān)控對方的運行狀況。當備份機不能在一定的時間內(nèi)收到這樣的信息時,它就接管主服務器的服務IP并繼續(xù)提供負載均衡服務;當備份管理器又從主管理器收到“I am alive”這樣的信息時,它就釋放服務IP地址,這樣的主服務器就開始再次提供負載均衡服務
2. keepalived原理
我們可以通過 keepalived 來實現(xiàn) Nginx 的高可用,keepalived 是集群管理中保證集群高可用的一個服務軟件,用來防止單點故障。Keepalived的作用是檢測 web 服務器的狀態(tài),如果有一臺 web 服務器死機或工作出現(xiàn)故障,Keepalived 將能檢測到,并將有故障的 web 服務器從系統(tǒng)中剔除,當web服務器工作正常后 Keepalived 會自動將該 web 服務器加入到服務器群中。這些工作全部都會自動完成,不需要人工干涉,需要人工做的只是修復故障的web服務器。keepalived 可以理解為一個健康檢查的軟件。
keepalived工作在IP/TCP協(xié)議棧的IP層,TCP層,及應用層,工作原理基于VRRP協(xié)議。
網(wǎng)絡(luò)層(layer 3):Keepalived會定期向服務器群中的服務器發(fā)送一個ICMP的數(shù)據(jù)包,(既我們平時用的Ping程序), 如果發(fā)現(xiàn)某臺服務的IP地址沒有激活,Keepalived便報告這臺服務器失效,并將它從服務器群中剔除。
傳輸層(layer 4):Keepalived以TCP端口的狀態(tài)來決定服務器工作正常與否,如web server的服務端口一般是80, 如果Keepalived檢測到80端口沒有啟動,則Keepalived將把這臺服務器從服務器群中剔除。
應用層(layer 5):只要針對應用上的一些探測方式,如URL的get請求,或者對nginx腳本檢測等; 可以根據(jù)用戶自定義添加腳本針對特定的服務進行狀態(tài)檢測,當檢測結(jié)果與用戶設(shè)定不一致,則把這臺服務器從服務器群中剔除
VRRP(Virtual Router Redundancy Protocol)虛擬路由冗余協(xié)議是一種容錯的主備模式的協(xié)議, 當網(wǎng)絡(luò)設(shè)備發(fā)生故障時,可以不影響主機之間通信情況下自動進行設(shè)備切換
高可用至少需要 2 臺服務器,主備都得裝上keepalived,當請求訪問主服務器時,備份服務器會一直檢查主服務器的狀態(tài)。
keepalived 需要綁定一個虛擬地址 vip ( Virtual IP Address ) ,這個虛擬 ip 地址綁定在哪臺服務器上請求就會發(fā)送到哪臺服務器,一開始會綁定在主服務器上

3. 安裝keepalived
首先準備兩臺服務器,這里我們準備了兩臺虛擬機。分別在這兩臺服務器上安裝 Nginx 和 keepalived
nginx使用docker部署;keepalived使用傳統(tǒng)部署
官方文檔:https://www.keepalived.org/doc/installing_keepalived.html
官方下載文檔:https://www.keepalived.org/download.html

這里下載最新的版本V2.2.8
1. 安裝依賴
On RHEL/centos, install the following prerequisites:
yum install curl gcc openssl-devel libnl3-devel net-snmp-devel
On Debian, install the following prerequisites:
apt-get install curl gcc libssl-dev libnl-3-dev libnl-genl-3-dev libsnmp-dev
2. 解壓并編譯、安裝
tar -xzvf keepalived-2.2.8.tar.gz
cd keepalived-2.2.8
./configure --prefix=/usr/local/keepalived-2.2.8 --sysconf=/etc
prefix:keepalived安裝位置
sysconf:keepalived配置文件位置,默認/etc
編譯:
make
安裝:
sudo make install
3. 配置
創(chuàng)建/etc/keepalived/keepalived.conf配置文件:
主節(jié)點(master)配置:
global_defs { router_id LVS_DEVEL } vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 1 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.110.100 } }
備節(jié)點(backup)配置:
global_defs { router_id LVS_DEVEL } vrrp_instance VI_1 { state BACKUP interface wlp2s0 virtual_router_id 2 priority 90 advert_int 1 nopreemt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.110.100 } }
state MASTER 表示該節(jié)點為主節(jié)點;
virtual_router_id 1 虛擬路由id,取值范圍0-255,主節(jié)點(MASTER)和子節(jié)點(BACKUP)不要設(shè)置一致;
interface ens33 指定網(wǎng)卡名稱,使用ip addr查看;
advert_int 1 主、子節(jié)點心跳頻率,單位為秒
authentication 用戶名密碼,主節(jié)點(MASTER)和子節(jié)點(BACKUP)設(shè)置一致;
virtual_ipaddress { 192.168.110.100 }虛擬IP(VIP)地址,待會測試就是使用該IP地址訪問;最好跟服務器同一個網(wǎng)段;主節(jié)點(MASTER)和子節(jié)點(BACKUP)設(shè)置一致;
4. 啟動停止
1. 啟動
sudo systemctl start keepalived
2. 重啟
sudo systemctl restart keepalived
3. 停止docker
sudo systemctl stop keepalived
4. 查看運行狀態(tài)
sudo systemctl status keepalived
5. 設(shè)置開機自啟
sudo systemctl enable keepalived
注意:
1. keepalived關(guān)閉了任然會有緩存, Keepalived 切換 VIP 的過程可能需要一些時間。在 Keepalived 停止后,VIP 可能仍然存在一段時間,直到漂移完成
2. 訪問VIP映射到對應的keepalived的Nginx,如果對應的Nginx停止了keepalived還存在,不會進行漂移就訪問不到Nginx了,因此需要設(shè)置定時檢查腳本
3. 如果主備機器之間的通信出了網(wǎng)題,就會發(fā)生腦裂,此時keepalived體系中會出現(xiàn)雙主的情況,產(chǎn)生資源競爭,一般可以引入仲裁來解決這個問題,即每個節(jié)點必須判斷自身的狀態(tài)。最簡單的一種操作方法是,在主備的keepalived的配置文件中增加check配置,服務器周期性地ping一下網(wǎng)關(guān),如果ping不通則認為自身有問題
5. 檢測nginx腳本
1. 檢測nginx腳本:nginx_check.sh
在/etc/keepalived/nginx_check.sh 腳本位置
內(nèi)容:
#!/bin/bash # 容器名稱 container_name="keep-nginx" # 檢查容器狀態(tài) container_status=$(docker inspect -f '{{.State.Status}}' $container_name 2>/dev/null) if [ -z "$container_status" ]; then echo "容器 $container_name 不存在! 關(guān)閉keepalived " systemctl stop keepalived echo "Keepalived 已關(guān)閉。" exit 1 fi echo "容器 $container_name 當前狀態(tài)為: $container_status" # 判斷容器是否處于 up 狀態(tài) if [ "$container_status" != "running" ]; then echo "容器不是 up 狀態(tài),將關(guān)閉 Keepalived。" systemctl stop keepalived # 停止 Keepalived 服務 echo "Keepalived 已關(guān)閉。" else echo "容器處于 up 狀態(tài),無需關(guān)閉 Keepalived。" fi
說明:檢查Nginx容器狀態(tài)是不是up狀態(tài),如果說明這個Nginx容器掛了,停止keepalived
2. 修改nginx_check.sh權(quán)限
chmod +x nginx_check.sh
3. 修改keepalived.conf配置文件
主節(jié)點:
global_defs { router_id LVS_DEVEL } vrrp_script chk_nginx { script "/etc/keepalived/nginx_check.sh" interval 2 weight 0 } vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 1 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.110.100 } track_script { chk_nginx } }
備節(jié)點:
global_defs { router_id LVS_DEVEL } vrrp_script chk_nginx { script "/etc/keepalived/nginx_check.sh" interval 2 weight 0 } vrrp_instance VI_1 { state BACKUP interface wlp2s0 virtual_router_id 2 priority 90 advert_int 1 nopreemt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.110.100 } track_script { chk_nginx } }
重啟主、備節(jié)點的keepalived使其配置生效
-
vrrp_script chk_nginx: 這一行定義了一個名為chk_nginx的 VRRP 腳本。VRRP 腳本用于在 VRRP 實例之間共享信息,以便在狀態(tài)切換時觸發(fā)一些動作。 -
script "/etc/keepalived/nginx_check.sh": 這一行指定了實際的腳本文件路徑。在這個例子中,腳本的路徑是/etc/keepalived/nginx_check.sh。這個腳本通常會包含一些邏輯,用于檢測 Nginx 服務的健康狀態(tài)。 -
interval 2: 這一行定義了腳本執(zhí)行的時間間隔。在這個例子中,腳本每隔 2 秒執(zhí)行一次。這意味著 Keepalived 將每隔 2 秒調(diào)用一次nginx_check.sh腳本來檢查 Nginx 服務的狀態(tài)。
-
track_script: 這是 VRRP 實例配置中的一個部分,用于指定要跟蹤的腳本。 -
chk_nginx: 這是先前定義的 VRRP 腳本的名稱。通過將chk_nginx包含在track_script中,你告訴 Keepalived 在狀態(tài)追蹤時使用chk_nginx腳本的結(jié)果。

浙公網(wǎng)安備 33010602011771號