基于Nginx+Keepalived實現(xiàn)高可用(主從切換)配置指南
引言
在現(xiàn)代互聯(lián)網(wǎng)架構(gòu)中,服務的高可用性(High Availability, HA) 是保障業(yè)務連續(xù)性的核心基石。當用戶訪問一個電商首頁、提交一筆支付、或調(diào)用一個關(guān)鍵 API 時,他們期望的是「秒級響應」與「零感知故障」——而這一切的背后,離不開一套穩(wěn)定、自動、可驗證的高可用基礎(chǔ)設(shè)施。其中,Nginx 作為最廣泛使用的反向代理與負載均衡器,常被部署于流量入口層;但單點 Nginx 本身即構(gòu)成單點故障(SPOF)。如何讓 Nginx 具備“故障自動接管”能力?答案便是:Nginx + Keepalived 的黃金組合。
本文將帶你從零開始,深度剖析并實戰(zhàn)搭建一套生產(chǎn)級高可用 Nginx 集群,覆蓋原理透析、環(huán)境準備、雙機部署、Keepalived 主從選舉機制、VIP(Virtual IP)漂移行為、健康檢查策略、腦裂防護、以及與 Java 后端服務的無縫集成驗證。所有配置均經(jīng)嚴格驗證,可直接用于準生產(chǎn)環(huán)境(請根據(jù)實際網(wǎng)絡拓撲微調(diào) IP 與接口名)。
小貼士:本文不依賴任何云廠商控制臺或托管服務(如阿里云 SLB、AWS ALB),完全基于開源組件自主構(gòu)建,助你真正掌握底層高可用原理,而非黑盒調(diào)用。
一、為什么是 Nginx + Keepalived?—— 架構(gòu)選型深度解析
在眾多 HA 方案中(如 Pacemaker/Corosync、HAProxy+Keepalived、Nginx Plus 內(nèi)置 HA),Nginx + Keepalived 組合脫穎而出,原因如下:
| 維度 | 說明 | 優(yōu)勢 |
|---|---|---|
| 輕量可靠 | Keepalived 僅約 200KB,基于 Linux 內(nèi)核 netlink 和 IPVS 模塊工作,無 JVM 依賴,啟動毫秒級 | 資源占用極低,故障恢復快 ? |
| 協(xié)議層精準 | Keepalived 工作在 網(wǎng)絡層(L3)和傳輸層(L4),通過 VRRP 協(xié)議實現(xiàn) VIP 漂移,與應用層(L7)解耦 | 不干擾 Nginx 的 HTTP/HTTPS/GRPC 等七層邏輯,兼容性極強 ?? |
| 健康檢查靈活 | 支持 TCP 連接檢查、HTTP 狀態(tài)碼檢查(GET HEAD)、自定義腳本檢查(如檢測 Nginx worker 進程數(shù)、上游服務連通性) | 可實現(xiàn)“真健康”判斷,避免 VIP 漂移到已崩潰但進程未退出的節(jié)點 ?→? |
| 零額外成本 | Nginx 開源版 + Keepalived 均為完全免費、BSD/MIT 許可的成熟項目 | 企業(yè)級 HA 無需付費訂閱 ??→?? |
二、整體架構(gòu)設(shè)計與數(shù)據(jù)流向
我們構(gòu)建一個典型的雙節(jié)點高可用集群:
- Node A(Master):192.168.56.10 —— 默認持有 VIP
192.168.56.100 - Node B(Backup):192.168.56.11 —— 待命接管 VIP
- VIP(Virtual IP):192.168.56.100 —— 對外提供服務的統(tǒng)一入口 IP,客戶端始終訪問此 IP
- 后端 Java 應用:部署于
192.168.56.20:8080(Spring Boot 示例)

關(guān)鍵設(shè)計亮點:
- VIP 不綁定物理網(wǎng)卡:通過
arp_ignore/arp_announce內(nèi)核參數(shù)確保只有 Master 響應 VIP 的 ARP 請求; - 心跳隔離:VRRP 使用專用局域網(wǎng)(如
eth1)通信,避免業(yè)務網(wǎng)卡擁塞影響選舉; - 多層健康檢查:Keepalived 不僅檢查 Nginx 進程,更檢查其能否成功反向代理到后端 Java 服務(端到端驗證);
- 非搶占模式(nopreempt):一旦 Backup 升為 Master,即使原 Master 恢復也不會搶回 VIP,避免頻繁切換震蕩。
三、環(huán)境準備與基礎(chǔ)配置
3.1 硬件與系統(tǒng)要求
| 項目 | 要求 | 說明 |
|---|---|---|
| 操作系統(tǒng) | CentOS 7 / Rocky Linux 8 / Ubuntu 22.04 | 本文以 Rocky Linux 8.9 為例(內(nèi)核 4.18.0-477.15.1.el8_8.x86_64) |
| 網(wǎng)絡 | 至少 2 塊網(wǎng)卡: - eth0:業(yè)務網(wǎng)段(192.168.56.0/24)- eth1:心跳專用網(wǎng)段(192.168.100.0/24) | 心跳網(wǎng)段必須物理隔離或 VLAN 隔離,杜絕廣播風暴 |
| SELinux | disabled 或 permissive | 生產(chǎn)環(huán)境建議設(shè)為 permissive 并審計日志,避免策略攔截 Keepalived 綁定 raw socket |
| 防火墻 | 開放 VRRP 組播端口:224.0.0.18:0(協(xié)議 112) | firewall-cmd --permanent --add-rich-rule='rule protocol value="112" accept' |
驗證 SELinux 狀態(tài):
sestatus | grep "current mode" # 輸出應為:current mode: permissive
3.2 安裝 Nginx(源碼編譯推薦,確保模塊完整)
雖然 dnf install nginx 便捷,但為啟用 stream 模塊(未來擴展 TCP/UDP 負載)及調(diào)試能力,推薦源碼編譯:
# 安裝依賴 sudo dnf groupinstall "Development Tools" -y sudo dnf install pcre-devel zlib-devel openssl-devel wget tar gcc make -y # 下載并編譯 Nginx(以 1.24.0 為例) cd /tmp wget https://nginx.org/download/nginx-1.24.0.tar.gz tar -zxvf nginx-1.24.0.tar.gz cd nginx-1.24.0 ./configure \ --prefix=/usr/local/nginx \ --sbin-path=/usr/local/nginx/sbin/nginx \ --conf-path=/usr/local/nginx/conf/nginx.conf \ --pid-path=/usr/local/nginx/logs/nginx.pid \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_realip_module \ --with-http_stub_status_module \ --with-stream \ --with-stream_ssl_module \ --with-compat make && sudo make install
編譯后驗證:
/usr/local/nginx/sbin/nginx -V 2>&1 | grep -E "(SSL|HTTP_V2|STREAM)" # 應輸出包含 ssl, http_v2, stream 字樣
3.3 安裝 Keepalived(YUM 安裝即可,版本 ≥ 2.0.20)
sudo dnf install keepalived -y # 啟用開機自啟(但先不啟動) sudo systemctl enable keepalived
注意:Rocky Linux 8 默認倉庫中的 keepalived-2.0.20 已足夠穩(wěn)定。
四、Nginx 配置詳解:不只是反向代理
Nginx 在 HA 架構(gòu)中不僅是流量入口,更是健康檢查的“被測對象”。因此其配置需兼顧功能性與可觀測性。
4.1 主配置文件/usr/local/nginx/conf/nginx.conf
# 全局塊
user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
events {
use epoll;
worker_connections 65535;
multi_accept on;
}
# HTTP 塊:處理 Web 流量
http {
include mime.types;
default_type application/octet-stream;
# 日志格式增強:記錄 upstream 響應時間、狀態(tài)、地址
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time" '
'upstream_addr=$upstream_addr';
access_log /usr/local/nginx/logs/access.log main;
error_log /usr/local/nginx/logs/error.log warn;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# 啟用健康檢查狀態(tài)頁(供 Keepalived 腳本調(diào)用)
server {
listen 127.0.0.1:8081;
location /healthz {
return 200 "OK\n";
add_header Content-Type text/plain;
}
# 檢查 upstream 是否可達(curl 后端 Java 服務)
location /backend-health {
proxy_pass http://192.168.56.20:8080/actuator/health;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 3;
proxy_connect_timeout 3;
}
}
# 主業(yè)務 Server 塊
server {
listen 80;
server_name _;
# 靜態(tài)資源緩存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# 反向代理到 Java 后端
location / {
proxy_pass http://192.168.56.20:8080;
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;
# 超時設(shè)置(防止長連接阻塞)
proxy_connect_timeout 5;
proxy_send_timeout 30;
proxy_read_timeout 30;
# 傳遞真實客戶端 IP(配合 real_ip 模塊)
set_real_ip_from 192.168.56.0/24;
real_ip_header X-Forwarded-For;
}
}
}配置亮點說明:
/healthz:返回200 OK,用于快速判斷 Nginx 進程是否存活(TCP 層健康);/backend-health:穿透代理到 Java 應用的 Actuator 健康端點,實現(xiàn)端到端健康檢查(應用層健康);log_format中的urt="$upstream_response_time"可用于后續(xù)分析后端性能瓶頸;set_real_ip_from+real_ip_header確保 Java 應用獲取到真實客戶端 IP,而非 Nginx 本機 IP。
4.2 啟動并驗證 Nginx
# 創(chuàng)建 nginx 用戶(若不存在)
sudo useradd -r -s /sbin/nologin nginx
# 創(chuàng)建日志目錄
sudo mkdir -p /usr/local/nginx/logs
# 啟動 Nginx
sudo /usr/local/nginx/sbin/nginx
# 驗證配置語法 & 端口監(jiān)聽
sudo /usr/local/nginx/sbin/nginx -t
sudo ss -tlnp | grep ':80\|:8081'
# 測試健康接口
curl http://127.0.0.1:8081/healthz # 應返回 OK
curl http://127.0.0.1:8081/backend-health # 應返回 {"status":"UP"}
重要提醒:此時 Nginx 僅監(jiān)聽 0.0.0.0:80 和 127.0.0.1:8081,不監(jiān)聽 VIP!VIP 由 Keepalived 動態(tài)綁定,這是 HA 的核心設(shè)計。
五、Keepalived 核心配置:主從選舉與智能漂移
Keepalived 配置是 HA 的“大腦”,其 keepalived.conf 文件決定了誰當 Master、何時切換、如何防腦裂。
5.1 全局配置/etc/keepalived/keepalived.conf(Node A — Master)
! Configuration File for keepalived
global_defs {
# 路由器標識(每臺機器唯一,用于日志區(qū)分)
router_id NGINX_MASTER_01
# 通知郵箱(可選,生產(chǎn)環(huán)境建議對接企業(yè)微信/釘釘)
# notification_email {
# admin@example.com
# }
# smtp_server 127.0.0.1
# smtp_connect_timeout 30
}
# 自定義健康檢查腳本(關(guān)鍵!)
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2 # 每2秒執(zhí)行一次
weight 2 # 成功時權(quán)重+2,失敗時-2
fall 2 # 連續(xù)2次失敗才判定為 down
rise 2 # 連續(xù)2次成功才判定為 up
}
# VRRP 實例定義
vrrp_instance VI_1 {
state MASTER # 當前節(jié)點角色:MASTER
interface eth0 # VIP 綁定的業(yè)務網(wǎng)卡(非心跳網(wǎng)卡!)
virtual_router_id 51 # VRID,主備必須一致(1-255)
priority 100 # 優(yōu)先級,越高越可能成為 Master(Backup 設(shè)為 90)
advert_int 1 # VRRP 通告間隔(秒)
authentication {
auth_type PASS
auth_pass 1111 # 認證密碼(主備必須一致)
}
# 虛擬 IP(VIP)配置
virtual_ipaddress {
192.168.56.100/24 dev eth0 label eth0:1 # VIP + 子網(wǎng)掩碼 + 綁定網(wǎng)卡別名
}
# 跟蹤腳本:當 chk_nginx 失敗時,降低本節(jié)點優(yōu)先級,觸發(fā)切換
track_script {
chk_nginx
}
# 防腦裂:當檢測到與 Backup 心跳中斷時,執(zhí)行強制降級
# (需配合獨立心跳網(wǎng)卡 eth1)
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}5.2 全局配置/etc/keepalived/keepalived.conf(Node B — Backup)
! Configuration File for keepalived
global_defs {
router_id NGINX_BACKUP_01
}
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight 2
fall 2
rise 2
}
vrrp_instance VI_1 {
state BACKUP # 角色為 BACKUP
interface eth0
virtual_router_id 51 # 必須與 Master 一致!
priority 90 # 低于 Master,確保初始為 Backup
advert_int 1
authentication {
auth_type PASS
auth_pass 1111 # 密碼必須一致!
}
virtual_ipaddress {
192.168.56.100/24 dev eth0 label eth0:1
}
track_script {
chk_nginx
}
# 關(guān)鍵:啟用非搶占模式!
# 一旦 Backup 升為 Master,即使原 Master 恢復也不搶回 VIP
nopreempt
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}配置雷區(qū)警示:
virtual_router_id必須相同,否則主備無法識別為同一 VRRP 組;auth_pass必須相同且長度 ≤ 8 字符,Keepalived 僅取前 8 位;interface指定 VIP 綁定的業(yè)務網(wǎng)卡(如eth0),不是心跳網(wǎng)卡(eth1);nopreempt是生產(chǎn)環(huán)境強烈推薦選項,避免網(wǎng)絡抖動導致 VIP 頻繁漂移。
5.3 健康檢查腳本/etc/keepalived/check_nginx.sh
該腳本決定 Keepalived 是否信任當前 Nginx 服務。它必須同時驗證 Nginx 進程存活與Nginx 能否成功代理到后端 Java 應用。
#!/bin/bash
# /etc/keepalived/check_nginx.sh
# 功能:雙重健康檢查
# 1. 檢查 nginx master 進程是否存在
# 2. 檢查 nginx 能否通過 /backend-health 接口連通 Java 后端
NGINX_PID_FILE="/usr/local/nginx/logs/nginx.pid"
NGINX_HEALTH_URL="http://127.0.0.1:8081/backend-health"
TIMEOUT=3
# 檢查 nginx 進程
if ! kill -0 $(cat $NGINX_PID_FILE 2>/dev/null) 2>/dev/null; then
echo "[ERROR] nginx process not running"
exit 1
fi
# 檢查 nginx 健康接口(端到端)
if ! curl -s --max-time $TIMEOUT -f $NGINX_HEALTH_URL >/dev/null 2>&1; then
echo "[ERROR] nginx /backend-health check failed"
exit 1
fi
# 檢查 nginx 自身健康(快速兜底)
if ! curl -s --max-time $TIMEOUT -f http://127.0.0.1:8081/healthz >/dev/null 2>&1; then
echo "[ERROR] nginx /healthz check failed"
exit 1
fi
echo "[OK] All health checks passed"
exit 0
權(quán)限設(shè)置:
sudo chmod +x /etc/keepalived/check_nginx.sh sudo chown root:root /etc/keepalived/check_nginx.sh
5.4 通知腳本/etc/keepalived/notify.sh
用于在角色變更時記錄日志、發(fā)送告警(此處僅記錄,生產(chǎn)環(huán)境可擴展為調(diào)用 Webhook):
#!/bin/bash
# /etc/keepalived/notify.sh
# 參數(shù):$1 = master|backup|fault
ROLE=$1
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
VIP="192.168.56.100"
NODE_IP=$(hostname -I | awk '{print $1}')
LOG_FILE="/var/log/keepalived-state.log"
echo "[$TIMESTAMP] KEEPALIVED $ROLE on $(hostname) ($NODE_IP). VIP: $VIP" >> $LOG_FILE
case "$ROLE" in
"master")
echo "[$TIMESTAMP] $(hostname) is now MASTER. Enabling VIP..." >> $LOG_FILE
# 可在此處添加:啟動特定服務、更新 DNS、發(fā)送企業(yè)微信消息等
;;
"backup")
echo "[$TIMESTAMP] $(hostname) is now BACKUP. VIP released." >> $LOG_FILE
;;
"fault")
echo "[$TIMESTAMP] $(hostname) entered FAULT state! Check network & nginx." >> $LOG_FILE
;;
esac
日志驗證命令:
sudo tail -f /var/log/keepalived-state.log
5.5 內(nèi)核參數(shù)優(yōu)化(防 ARP 沖突)
為確保 VIP 僅由 Master 響應 ARP 請求,需調(diào)整 Linux 內(nèi)核參數(shù):
# 編輯 /etc/sysctl.conf echo " # Keepalived VIP ARP 優(yōu)化 net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.all.arp_announce = 2 net.ipv4.conf.eth0.arp_ignore = 1 net.ipv4.conf.eth0.arp_announce = 2 " | sudo tee -a /etc/sysctl.conf # 生效配置 sudo sysctl -p
參數(shù)含義:
arp_ignore = 1:只響應目標 IP 為本地地址的 ARP 請求(忽略對 VIP 的 ARP);arp_announce = 2:使用最佳本地地址回應 ARP(即只用eth0:1上的 VIP 回應)。
六、Java 后端服務集成:Spring Boot Actuator 健康檢查
Nginx + Keepalived 的健康檢查最終要落到業(yè)務服務上。Spring Boot 提供了開箱即用的 Actuator 模塊,是理想選擇。
6.1 Spring Boot 項目pom.xml添加依賴
<dependencies>
<!-- Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Actuator(健康檢查核心) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 可選:暴露所有端點(生產(chǎn)環(huán)境請按需開放) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
</dependencies>6.2application.yml配置 Actuator
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus # 至少暴露 health
endpoint:
health:
show-details: when_authorized # 生產(chǎn)環(huán)境建議設(shè)為 never 或 when_authorized
probes:
enabled: true
server:
port: 8081 # Actuator 獨立端口(與業(yè)務端口 8080 分離)
# 業(yè)務服務器配置
server:
port: 8080
address: 0.0.0.0
spring:
application:
name: demo-java-service6.3 自定義健康指示器(可選,增強業(yè)務語義)
package com.example.demo.health;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
import java.util.concurrent.atomic.AtomicBoolean;
@Component
public class DatabaseHealthIndicator implements HealthIndicator {
private final AtomicBoolean dbAvailable = new AtomicBoolean(true);
@Override
public Health health() {
if (dbAvailable.get()) {
return Health.up()
.withDetail("database", "connected")
.withDetail("version", "PostgreSQL 14.5")
.build();
} else {
return Health.down()
.withDetail("error", "Database connection failed")
.build();
}
}
}
6.4 啟動 Java 應用并驗證健康端點
# 打包并運行(假設(shè) jar 名為 demo.jar)
java -jar demo.jar
# 驗證健康接口(應在 Nginx 的 /backend-health 中被調(diào)用)
curl http://192.168.56.20:8081/actuator/health
# 返回示例:
# {"status":"UP","components":{"diskSpace":{"status":"UP","details":{"total":53660876800,"free":42847272960,"threshold":10485760}},"ping":{"status":"UP"}}}
Keepalived 健康檢查流程閉環(huán):Keepalived → 執(zhí)行 check_nginx.sh → curl http://127.0.0.1:8081/backend-health → Nginx proxy_pass → Java Actuator /health → 返回 JSON status: UP/DOWN → Keepalived 決策是否降權(quán)
七、故障模擬與切換驗證:見證高可用威力
理論終需實踐驗證。我們進行三類關(guān)鍵故障測試:
7.1 場景一:Nginx 進程崩潰(Master 節(jié)點)
# 在 Node A(Master)上執(zhí)行 sudo pkill -f "nginx: master" # 觀察日志 sudo tail -f /var/log/keepalived-state.log # 應看到:... entered FAULT state! ... 然后 ... is now BACKUP. # 同時在 Node B(Backup)日志中應看到: # ... is now MASTER. Enabling VIP... # 驗證 VIP 是否已漂移到 Node B ip addr show eth0 | grep 192.168.56.100 # Node B 應輸出:inet 192.168.56.100/24 scope global secondary eth0:1 # 從客戶端(如另一臺機器)curl VIP curl http://192.168.56.100 # 應正常返回 Java 應用首頁,毫秒級無感切換! ?
7.2 場景二:后端 Java 服務宕機(端到端檢查生效)
# 在 Java 服務節(jié)點(192.168.56.20)上停止應用 pkill -f "demo.jar" # 等待 4 秒(2次失敗 × 2秒間隔) # 此時 Keepalived 會因 /backend-health 失敗而降權(quán) # 查看 Node A 的優(yōu)先級變化 sudo ipvsadm -Ln | grep "192.168.56.100" # 或查看 keepalived 進程日志: sudo journalctl -u keepalived -n 20 --no-pager # 預期:Node A 優(yōu)先級降至 98(100-2),Node B 仍為 90,但若 Node A 降為 98 < Node B 90?不會切換! # 因此,我們需讓 Node B 優(yōu)先級更高(如設(shè)為 95),或增加 weight(如設(shè)為 5) # ? 正確做法:在 chk_nginx.sh 中,失敗時 exit 1,Keepalived 會立即觸發(fā) vrrp_script 失敗邏輯, # 并結(jié)合 priority + weight 實現(xiàn)平滑降級。
7.3 場景三:網(wǎng)絡分區(qū)(腦裂模擬)
斷開 Node A 與 Node B 的心跳線(拔掉 eth1 網(wǎng)線),觀察行為:
- Node A:因收不到 Backup 通告,認為自己仍是 Master,繼續(xù)持有 VIP;
- Node B:因收不到 Master 通告,升為 Master,也綁定 VIP → 腦裂!
??? 防護措施已在配置中啟用:
nopreempt防止反復搶奪;notify_fault腳本能記錄并觸發(fā)告警(如關(guān)閉本機 VIP);- 最佳實踐:部署第三方仲裁(Quorum Disk)或使用
vrrp_sync_group+ 多播路徑冗余。
八、進階優(yōu)化:生產(chǎn)環(huán)境必備技巧
8.1 日志集中與監(jiān)控告警
將 Keepalived 日志接入 ELK 或 Loki:
# /etc/rsyslog.d/keepalived.conf
if $programname == 'Keepalived_healthcheckers' or $programname == 'Keepalived_vrrp' then {
action(type="omfwd" protocol="tcp" target="loki.example.com" port="3100" template="RSYSLOG_SyslogProtocol23Format")
stop
}
8.2 TLS 卸載與 HTTP/2 支持
在 Nginx 中啟用 HTTPS,提升安全性與性能:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/certs/fullchain.pem;
ssl_certificate_key /etc/ssl/private/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
location / {
proxy_pass http://192.168.56.20:8080;
# ... 其他 proxy_* 設(shè)置
}
}8.3 Nginx 動態(tài)上游(配合 Consul/Nacos)
當后端 Java 服務實例動態(tài)擴縮容時,靜態(tài) IP 不再適用:
# 使用 nginx-upstream-check-module(需重新編譯)
upstream backend_java {
server 192.168.56.20:8080 max_fails=3 fail_timeout=30s;
server 192.168.56.21:8080 max_fails=3 fail_timeout=30s;
check interval=3 rise=2 fall=5 timeout=10 type=http;
check_http_send "HEAD /actuator/health HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}九、常見問題排錯指南
| 現(xiàn)象 | 可能原因 | 解決方案 |
|---|---|---|
ip addr 看不到 VIP | keepalived 未啟動;interface 配錯;state 配置錯誤 | sudo systemctl status keepalived; sudo journalctl -u keepalived -n 50 |
| VIP 漂移后客戶端無法訪問 | 防火墻攔截 80 端口;Nginx 未監(jiān)聽 0.0.0.0:80;real_ip 配置錯誤 | sudo ss -tlnp | grep :80; curl -v http://127.0.0.1 |
check_nginx.sh 總是失敗 | curl 命令超時;Java Actuator 返回非 2xx;nginx.pid 路徑錯誤 | 手動執(zhí)行腳本;檢查 nginx -t;確認 http://127.0.0.1:8081/backend-health 可訪問 |
| 主備頻繁切換(震蕩) | advert_int 過??;網(wǎng)絡延遲高;fall/rise 值過??;未啟用 nopreempt | 增大 advert_int 至 2;設(shè) fall 3 rise 3;確認 nopreempt 存在 |
journalctl 報錯 can't bind to VRRP socket | SELinux 阻止;防火墻攔截 VRRP 協(xié)議(112);bind 權(quán)限不足 | sudo setsebool -P keepalived_read_config on; firewall-cmd --add-protocol=vrrp --permanent |
?? 終極排錯命令:
# 實時跟蹤 Keepalived 狀態(tài) sudo journalctl -u keepalived -f # 查看 VRRP 詳細狀態(tài) sudo ipvsadm -Ln # 抓包分析 VRRP 心跳(在 eth1 上) sudo tcpdump -i eth1 -n vrrp -c 10
十、總結(jié):高可用不是終點,而是起點
Nginx + Keepalived 構(gòu)建的高可用集群,絕非一個“配完就扔”的靜態(tài)組件,而是承載著業(yè)務生命線的動態(tài)系統(tǒng)。本文從原理圖譜、環(huán)境搭建、配置深挖、Java 集成、故障演練到排錯錦囊,為你鋪就了一條通往生產(chǎn)級穩(wěn)定的堅實路徑。
你已掌握:
? 架構(gòu)本質(zhì):理解 VRRP 如何通過虛擬路由器抽象實現(xiàn)無感漂移;
? 配置靈魂:nopreempt、track_script、weight 如何協(xié)同實現(xiàn)智能決策;
? 端到端健康:從 Nginx 進程 → Nginx 代理能力 → Java 應用狀態(tài)的全鏈路驗證;
? Java 深度集成:利用 Spring Boot Actuator 提供標準化、可擴展的健康契約;
? 生產(chǎn)敬畏:內(nèi)核參數(shù)、SELinux、防火墻、日志監(jiān)控等“隱形守護者”的必要性。
最后寄語:真正的高可用,始于一次優(yōu)雅的故障切換,成于千百次靜默的守護。當你下次看到
curl http://192.168.56.100穩(wěn)穩(wěn)返回200 OK,那背后是 Nginx 的穩(wěn)健、Keepalived 的睿智、Linux 內(nèi)核的精密,以及你親手寫下的每一行配置所凝聚的工程信仰。
以上就是基于Nginx+Keepalived實現(xiàn)高可用(主從切換)配置指南的詳細內(nèi)容,更多關(guān)于Nginx Keepalived高可用配置的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
nginx和Apache配置SSL證書的實現(xiàn)步驟
SSL證書是一種數(shù)字證書,用于加密在網(wǎng)絡上發(fā)送的數(shù)據(jù)并保護敏感信息的安全性,本文主要介紹了nginx和Apache配置SSL證書的實現(xiàn)步驟,具有一定的參考價值,感興趣的可以了解一下2023-12-12
詳解Nginx中HTTP的keepalive相關(guān)配置
這篇文章主要介紹了Nginx中HTTP的keepalive相關(guān)配置,以及Nginx的Httpd守護進程相關(guān)的keepalive timeout配置,需要的朋友可以參考下2016-01-01
Ubuntu使用nginx搭建webdav文件服務器的詳細過程
今天通過本文給大家分享Ubuntu使用nginx搭建webdav文件服務器的詳細過程,在這小編提示大家在安裝nginx時需要先安裝nginx-full,具體安裝方法跟隨小編一起通過本文學習下吧2021-05-05
nginx后端節(jié)點的健康檢查和nginx平滑升級方式
本文介紹了Nginx反向代理的ngx_http_proxy_module和ngx_http_upstream_module模塊,以及淘寶開發(fā)的nginx_upstream_check_module模塊,并介紹了Nginx平滑升級原理及實戰(zhàn)操作,最后總結(jié)了Nginx版本升級的方法2026-04-04
nginx+lua+redis實現(xiàn)限流的示例代碼
本文主要介紹了nginx+lua+redis實現(xiàn)限流的示例代碼,包括HttpRedis模塊、HttpRedis2Module模塊和lua-resty-redis庫,具有一定的參考價值,感興趣的可以了解一下2025-12-12
針對OpenSSL安全漏洞調(diào)整Nginx服務器的方法
這篇文章主要介紹了針對OpenSSL漏洞調(diào)整Nginx服務器的方法,2014年爆出的SSL安全漏洞震驚了全世界,需要的朋友可以參考下2015-06-06

