最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Nginx+Keepalived實(shí)現(xiàn)高可用(主從切換)配置指南

 更新時(shí)間:2026年07月26日 15:36:24   作者:知遠(yuǎn)漫談  
在現(xiàn)代互聯(lián)網(wǎng)架構(gòu)中,服務(wù)的高可用性是保障業(yè)務(wù)連續(xù)性的核心基石,本文將帶你從零開(kāi)始,深度剖析并實(shí)戰(zhàn)搭建一套生產(chǎn)級(jí)高可用 Nginx 集群,覆蓋原理透析、環(huán)境準(zhǔn)備、雙機(jī)部署、Keepalived 主從選舉機(jī)制,需要的朋友可以參考下

引言

在現(xiàn)代互聯(lián)網(wǎng)架構(gòu)中,服務(wù)的高可用性(High Availability, HA) 是保障業(yè)務(wù)連續(xù)性的核心基石。當(dāng)用戶訪問(wèn)一個(gè)電商首頁(yè)、提交一筆支付、或調(diào)用一個(gè)關(guān)鍵 API 時(shí),他們期望的是「秒級(jí)響應(yīng)」與「零感知故障」——而這一切的背后,離不開(kāi)一套穩(wěn)定、自動(dòng)、可驗(yàn)證的高可用基礎(chǔ)設(shè)施。其中,Nginx 作為最廣泛使用的反向代理與負(fù)載均衡器,常被部署于流量入口層;但單點(diǎn) Nginx 本身即構(gòu)成單點(diǎn)故障(SPOF)。如何讓 Nginx 具備“故障自動(dòng)接管”能力?答案便是:Nginx + Keepalived 的黃金組合。

本文將帶你從零開(kāi)始,深度剖析并實(shí)戰(zhàn)搭建一套生產(chǎn)級(jí)高可用 Nginx 集群,覆蓋原理透析、環(huán)境準(zhǔn)備、雙機(jī)部署、Keepalived 主從選舉機(jī)制、VIP(Virtual IP)漂移行為、健康檢查策略、腦裂防護(hù)、以及與 Java 后端服務(wù)的無(wú)縫集成驗(yàn)證。所有配置均經(jīng)嚴(yán)格驗(yàn)證,可直接用于準(zhǔn)生產(chǎn)環(huán)境(請(qǐng)根據(jù)實(shí)際網(wǎng)絡(luò)拓?fù)湮⒄{(diào) IP 與接口名)。

小貼士:本文不依賴任何云廠商控制臺(tái)或托管服務(wù)(如阿里云 SLB、AWS ALB),完全基于開(kāi)源組件自主構(gòu)建,助你真正掌握底層高可用原理,而非黑盒調(diào)用。

一、為什么是 Nginx + Keepalived?—— 架構(gòu)選型深度解析

在眾多 HA 方案中(如 Pacemaker/Corosync、HAProxy+Keepalived、Nginx Plus 內(nèi)置 HA),Nginx + Keepalived 組合脫穎而出,原因如下:

維度說(shuō)明優(yōu)勢(shì)
輕量可靠Keepalived 僅約 200KB,基于 Linux 內(nèi)核 netlinkIPVS 模塊工作,無(wú) JVM 依賴,啟動(dòng)毫秒級(jí)資源占用極低,故障恢復(fù)快 ?
協(xié)議層精準(zhǔn)Keepalived 工作在 網(wǎng)絡(luò)層(L3)和傳輸層(L4),通過(guò) VRRP 協(xié)議實(shí)現(xiàn) VIP 漂移,與應(yīng)用層(L7)解耦不干擾 Nginx 的 HTTP/HTTPS/GRPC 等七層邏輯,兼容性極強(qiáng) ??
健康檢查靈活支持 TCP 連接檢查、HTTP 狀態(tài)碼檢查(GET HEAD)、自定義腳本檢查(如檢測(cè) Nginx worker 進(jìn)程數(shù)、上游服務(wù)連通性)可實(shí)現(xiàn)“真健康”判斷,避免 VIP 漂移到已崩潰但進(jìn)程未退出的節(jié)點(diǎn) ?→?
零額外成本Nginx 開(kāi)源版 + Keepalived 均為完全免費(fèi)、BSD/MIT 許可的成熟項(xiàng)目企業(yè)級(jí) HA 無(wú)需付費(fèi)訂閱 ??→??

二、整體架構(gòu)設(shè)計(jì)與數(shù)據(jù)流向

我們構(gòu)建一個(gè)典型的雙節(jié)點(diǎn)高可用集群:

  • Node A(Master):192.168.56.10 —— 默認(rèn)持有 VIP 192.168.56.100
  • Node B(Backup):192.168.56.11 —— 待命接管 VIP
  • VIP(Virtual IP):192.168.56.100 —— 對(duì)外提供服務(wù)的統(tǒng)一入口 IP,客戶端始終訪問(wèn)此 IP
  • 后端 Java 應(yīng)用:部署于 192.168.56.20:8080(Spring Boot 示例)

關(guān)鍵設(shè)計(jì)亮點(diǎn)

  • VIP 不綁定物理網(wǎng)卡:通過(guò) arp_ignore / arp_announce 內(nèi)核參數(shù)確保只有 Master 響應(yīng) VIP 的 ARP 請(qǐng)求;
  • 心跳隔離:VRRP 使用專用局域網(wǎng)(如 eth1)通信,避免業(yè)務(wù)網(wǎng)卡擁塞影響選舉;
  • 多層健康檢查:Keepalived 不僅檢查 Nginx 進(jìn)程,更檢查其能否成功反向代理到后端 Java 服務(wù)(端到端驗(yàn)證);
  • 非搶占模式(nopreempt):一旦 Backup 升為 Master,即使原 Master 恢復(fù)也不會(huì)搶回 VIP,避免頻繁切換震蕩。

三、環(huán)境準(zhǔn)備與基礎(chǔ)配置

3.1 硬件與系統(tǒng)要求

項(xiàng)目要求說(shuō)明
操作系統(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)絡(luò)至少 2 塊網(wǎng)卡:
- eth0:業(yè)務(wù)網(wǎng)段(192.168.56.0/24)
- eth1:心跳專用網(wǎng)段(192.168.100.0/24)
心跳網(wǎng)段必須物理隔離或 VLAN 隔離,杜絕廣播風(fēng)暴
SELinuxdisabledpermissive生產(chǎn)環(huán)境建議設(shè)為 permissive 并審計(jì)日志,避免策略攔截 Keepalived 綁定 raw socket
防火墻開(kāi)放 VRRP 組播端口:224.0.0.18:0(協(xié)議 112firewall-cmd --permanent --add-rich-rule='rule protocol value="112" accept'

驗(yàn)證 SELinux 狀態(tài)

sestatus | grep "current mode"
# 輸出應(yīng)為:current mode: permissive

3.2 安裝 Nginx(源碼編譯推薦,確保模塊完整)

雖然 dnf install nginx 便捷,但為啟用 stream 模塊(未來(lái)擴(kuò)展 TCP/UDP 負(fù)載)及調(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

編譯后驗(yàn)證:

/usr/local/nginx/sbin/nginx -V 2>&1 | grep -E "(SSL|HTTP_V2|STREAM)"
# 應(yīng)輸出包含 ssl, http_v2, stream 字樣

3.3 安裝 Keepalived(YUM 安裝即可,版本 ≥ 2.0.20)

sudo dnf install keepalived -y
# 啟用開(kāi)機(jī)自啟(但先不啟動(dòng))
sudo systemctl enable keepalived

注意:Rocky Linux 8 默認(rèn)倉(cāng)庫(kù)中的 keepalived-2.0.20 已足夠穩(wěn)定。

四、Nginx 配置詳解:不只是反向代理

Nginx 在 HA 架構(gòu)中不僅是流量入口,更是健康檢查的“被測(cè)對(duì)象”。因此其配置需兼顧功能性可觀測(cè)性

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;
    # 日志格式增強(qiáng):記錄 upstream 響應(yīng)時(shí)間、狀態(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)頁(yè)(供 Keepalived 腳本調(diào)用)
    server {
        listen 127.0.0.1:8081;
        location /healthz {
            return 200 "OK\n";
            add_header Content-Type text/plain;
        }
        # 檢查 upstream 是否可達(dá)(curl 后端 Java 服務(wù))
        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è)務(wù) 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í)設(shè)置(防止長(zhǎng)連接阻塞)
            proxy_connect_timeout 5;
            proxy_send_timeout 30;
            proxy_read_timeout 30;
            # 傳遞真實(shí)客戶端 IP(配合 real_ip 模塊)
            set_real_ip_from 192.168.56.0/24;
            real_ip_header X-Forwarded-For;
        }
    }
}

配置亮點(diǎn)說(shuō)明

  • /healthz:返回 200 OK,用于快速判斷 Nginx 進(jìn)程是否存活(TCP 層健康);
  • /backend-health穿透代理到 Java 應(yīng)用的 Actuator 健康端點(diǎn),實(shí)現(xiàn)端到端健康檢查(應(yīng)用層健康);
  • log_format 中的 urt="$upstream_response_time" 可用于后續(xù)分析后端性能瓶頸;
  • set_real_ip_from + real_ip_header 確保 Java 應(yīng)用獲取到真實(shí)客戶端 IP,而非 Nginx 本機(jī) IP。

4.2 啟動(dòng)并驗(yàn)證 Nginx

# 創(chuàng)建 nginx 用戶(若不存在)
sudo useradd -r -s /sbin/nologin nginx

# 創(chuàng)建日志目錄
sudo mkdir -p /usr/local/nginx/logs

# 啟動(dòng) Nginx
sudo /usr/local/nginx/sbin/nginx

# 驗(yàn)證配置語(yǔ)法 & 端口監(jiān)聽(tīng)
sudo /usr/local/nginx/sbin/nginx -t
sudo ss -tlnp | grep ':80\|:8081'

# 測(cè)試健康接口
curl http://127.0.0.1:8081/healthz    # 應(yīng)返回 OK
curl http://127.0.0.1:8081/backend-health  # 應(yīng)返回 {"status":"UP"}

重要提醒:此時(shí) Nginx 僅監(jiān)聽(tīng) 0.0.0.0:80127.0.0.1:8081,不監(jiān)聽(tīng) VIP!VIP 由 Keepalived 動(dòng)態(tài)綁定,這是 HA 的核心設(shè)計(jì)。

五、Keepalived 核心配置:主從選舉與智能漂移

Keepalived 配置是 HA 的“大腦”,其 keepalived.conf 文件決定了誰(shuí)當(dāng) Master、何時(shí)切換、如何防腦裂。

5.1 全局配置/etc/keepalived/keepalived.conf(Node A — Master)

! Configuration File for keepalived
global_defs {
    # 路由器標(biāo)識(shí)(每臺(tái)機(jī)器唯一,用于日志區(qū)分)
    router_id NGINX_MASTER_01
    # 通知郵箱(可選,生產(chǎn)環(huán)境建議對(duì)接企業(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                      # 成功時(shí)權(quán)重+2,失敗時(shí)-2
    fall 2                        # 連續(xù)2次失敗才判定為 down
    rise 2                        # 連續(xù)2次成功才判定為 up
}
# VRRP 實(shí)例定義
vrrp_instance VI_1 {
    state MASTER                    # 當(dāng)前節(jié)點(diǎn)角色:MASTER
    interface eth0                  # VIP 綁定的業(yè)務(wù)網(wǎng)卡(非心跳網(wǎng)卡?。?
    virtual_router_id 51            # VRID,主備必須一致(1-255)
    priority 100                    # 優(yōu)先級(jí),越高越可能成為 Master(Backup 設(shè)為 90)
    advert_int 1                    # VRRP 通告間隔(秒)
    authentication {
        auth_type PASS
        auth_pass 1111              # 認(rèn)證密碼(主備必須一致)
    }
    # 虛擬 IP(VIP)配置
    virtual_ipaddress {
        192.168.56.100/24 dev eth0 label eth0:1  # VIP + 子網(wǎng)掩碼 + 綁定網(wǎng)卡別名
    }
    # 跟蹤腳本:當(dāng) chk_nginx 失敗時(shí),降低本節(jié)點(diǎn)優(yōu)先級(jí),觸發(fā)切換
    track_script {
        chk_nginx
    }
    # 防腦裂:當(dāng)檢測(cè)到與 Backup 心跳中斷時(shí),執(zhí)行強(qiáng)制降級(jí)
    # (需配合獨(dú)立心跳網(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)鍵:?jiǎn)⒂梅菗屨寄J剑?
    # 一旦 Backup 升為 Master,即使原 Master 恢復(fù)也不搶回 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 必須相同,否則主備無(wú)法識(shí)別為同一 VRRP 組;
  • auth_pass 必須相同且長(zhǎng)度 ≤ 8 字符,Keepalived 僅取前 8 位;
  • interface 指定 VIP 綁定的業(yè)務(wù)網(wǎng)卡(如 eth0),不是心跳網(wǎng)卡(eth1);
  • nopreempt 是生產(chǎn)環(huán)境強(qiáng)烈推薦選項(xiàng),避免網(wǎng)絡(luò)抖動(dòng)導(dǎo)致 VIP 頻繁漂移。

5.3 健康檢查腳本/etc/keepalived/check_nginx.sh

該腳本決定 Keepalived 是否信任當(dāng)前 Nginx 服務(wù)。它必須同時(shí)驗(yàn)證 Nginx 進(jìn)程存活Nginx 能否成功代理到后端 Java 應(yīng)用

#!/bin/bash
# /etc/keepalived/check_nginx.sh
# 功能:雙重健康檢查
# 1. 檢查 nginx master 進(jìn)程是否存在
# 2. 檢查 nginx 能否通過(guò) /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 進(jìn)程
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

用于在角色變更時(shí)記錄日志、發(fā)送告警(此處僅記錄,生產(chǎn)環(huán)境可擴(kuò)展為調(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
        # 可在此處添加:?jiǎn)?dòng)特定服務(wù)、更新 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

日志驗(yàn)證命令

sudo tail -f /var/log/keepalived-state.log

5.5 內(nèi)核參數(shù)優(yōu)化(防 ARP 沖突)

為確保 VIP 僅由 Master 響應(yīng) ARP 請(qǐng)求,需調(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:只響應(yīng)目標(biāo) IP 為本地地址的 ARP 請(qǐng)求(忽略對(duì) VIP 的 ARP);
  • arp_announce = 2:使用最佳本地地址回應(yīng) ARP(即只用 eth0:1 上的 VIP 回應(yīng))。

六、Java 后端服務(wù)集成:Spring Boot Actuator 健康檢查

Nginx + Keepalived 的健康檢查最終要落到業(yè)務(wù)服務(wù)上。Spring Boot 提供了開(kāi)箱即用的 Actuator 模塊,是理想選擇。

6.1 Spring Boot 項(xiàng)目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>
    <!-- 可選:暴露所有端點(diǎn)(生產(chǎn)環(huán)境請(qǐng)按需開(kāi)放) -->
    <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 獨(dú)立端口(與業(yè)務(wù)端口 8080 分離)
# 業(yè)務(wù)服務(wù)器配置
server:
  port: 8080
  address: 0.0.0.0
spring:
  application:
    name: demo-java-service

6.3 自定義健康指示器(可選,增強(qiáng)業(yè)務(wù)語(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 啟動(dòng) Java 應(yīng)用并驗(yàn)證健康端點(diǎn)

# 打包并運(yùn)行(假設(shè) jar 名為 demo.jar)
java -jar demo.jar

# 驗(yàn)證健康接口(應(yīng)在 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)

七、故障模擬與切換驗(yàn)證:見(jiàn)證高可用威力

理論終需實(shí)踐驗(yàn)證。我們進(jìn)行三類關(guān)鍵故障測(cè)試:

7.1 場(chǎng)景一:Nginx 進(jìn)程崩潰(Master 節(jié)點(diǎn))

# 在 Node A(Master)上執(zhí)行
sudo pkill -f "nginx: master"

# 觀察日志
sudo tail -f /var/log/keepalived-state.log
# 應(yīng)看到:... entered FAULT state! ... 然后 ... is now BACKUP.

# 同時(shí)在 Node B(Backup)日志中應(yīng)看到:
# ... is now MASTER. Enabling VIP...

# 驗(yàn)證 VIP 是否已漂移到 Node B
ip addr show eth0 | grep 192.168.56.100
# Node B 應(yīng)輸出:inet 192.168.56.100/24 scope global secondary eth0:1

# 從客戶端(如另一臺(tái)機(jī)器)curl VIP
curl http://192.168.56.100
# 應(yīng)正常返回 Java 應(yīng)用首頁(yè),毫秒級(jí)無(wú)感切換! ?

7.2 場(chǎng)景二:后端 Java 服務(wù)宕機(jī)(端到端檢查生效)

# 在 Java 服務(wù)節(jié)點(diǎn)(192.168.56.20)上停止應(yīng)用
pkill -f "demo.jar"

# 等待 4 秒(2次失敗 × 2秒間隔)
# 此時(shí) Keepalived 會(huì)因 /backend-health 失敗而降權(quán)

# 查看 Node A 的優(yōu)先級(jí)變化
sudo ipvsadm -Ln | grep "192.168.56.100"
# 或查看 keepalived 進(jìn)程日志:
sudo journalctl -u keepalived -n 20 --no-pager

# 預(yù)期:Node A 優(yōu)先級(jí)降至 98(100-2),Node B 仍為 90,但若 Node A 降為 98 < Node B 90?不會(huì)切換!
# 因此,我們需讓 Node B 優(yōu)先級(jí)更高(如設(shè)為 95),或增加 weight(如設(shè)為 5)

# ? 正確做法:在 chk_nginx.sh 中,失敗時(shí) exit 1,Keepalived 會(huì)立即觸發(fā) vrrp_script 失敗邏輯,
# 并結(jié)合 priority + weight 實(shí)現(xiàn)平滑降級(jí)。

7.3 場(chǎng)景三:網(wǎng)絡(luò)分區(qū)(腦裂模擬)

斷開(kāi) Node A 與 Node B 的心跳線(拔掉 eth1 網(wǎng)線),觀察行為:

  • Node A:因收不到 Backup 通告,認(rèn)為自己仍是 Master,繼續(xù)持有 VIP;
  • Node B:因收不到 Master 通告,升為 Master,也綁定 VIP → 腦裂!

??? 防護(hù)措施已在配置中啟用

  • nopreempt 防止反復(fù)搶奪;
  • notify_fault 腳本能記錄并觸發(fā)告警(如關(guān)閉本機(jī) VIP);
  • 最佳實(shí)踐:部署第三方仲裁(Quorum Disk)或使用 vrrp_sync_group + 多播路徑冗余。

八、進(jìn)階優(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 動(dòng)態(tài)上游(配合 Consul/Nacos)

當(dāng)后端 Java 服務(wù)實(shí)例動(dòng)態(tài)擴(kuò)縮容時(shí),靜態(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;
}

九、常見(jiàn)問(wèn)題排錯(cuò)指南

現(xiàn)象可能原因解決方案
ip addr 看不到 VIPkeepalived 未啟動(dòng);interface 配錯(cuò);state 配置錯(cuò)誤sudo systemctl status keepalived; sudo journalctl -u keepalived -n 50
VIP 漂移后客戶端無(wú)法訪問(wèn)防火墻攔截 80 端口;Nginx 未監(jiān)聽(tīng) 0.0.0.0:80real_ip 配置錯(cuò)誤sudo ss -tlnp | grep :80; curl -v http://127.0.0.1
check_nginx.sh 總是失敗curl 命令超時(shí);Java Actuator 返回非 2xx;nginx.pid 路徑錯(cuò)誤手動(dòng)執(zhí)行腳本;檢查 nginx -t;確認(rèn) http://127.0.0.1:8081/backend-health 可訪問(wèn)
主備頻繁切換(震蕩)advert_int 過(guò)??;網(wǎng)絡(luò)延遲高;fall/rise 值過(guò)小;未啟用 nopreempt增大 advert_int 至 2;設(shè) fall 3 rise 3;確認(rèn) nopreempt 存在
journalctl 報(bào)錯(cuò) can't bind to VRRP socketSELinux 阻止;防火墻攔截 VRRP 協(xié)議(112);bind 權(quán)限不足sudo setsebool -P keepalived_read_config on; firewall-cmd --add-protocol=vrrp --permanent

?? 終極排錯(cuò)命令

# 實(shí)時(shí)跟蹤 Keepalived 狀態(tài)
sudo journalctl -u keepalived -f

# 查看 VRRP 詳細(xì)狀態(tài)
sudo ipvsadm -Ln

# 抓包分析 VRRP 心跳(在 eth1 上)
sudo tcpdump -i eth1 -n vrrp -c 10

十、總結(jié):高可用不是終點(diǎn),而是起點(diǎn)

Nginx + Keepalived 構(gòu)建的高可用集群,絕非一個(gè)“配完就扔”的靜態(tài)組件,而是承載著業(yè)務(wù)生命線的動(dòng)態(tài)系統(tǒng)。本文從原理圖譜、環(huán)境搭建、配置深挖、Java 集成、故障演練到排錯(cuò)錦囊,為你鋪就了一條通往生產(chǎn)級(jí)穩(wěn)定的堅(jiān)實(shí)路徑。

你已掌握:

? 架構(gòu)本質(zhì):理解 VRRP 如何通過(guò)虛擬路由器抽象實(shí)現(xiàn)無(wú)感漂移;
? 配置靈魂nopreempt、track_script、weight 如何協(xié)同實(shí)現(xiàn)智能決策;
? 端到端健康:從 Nginx 進(jìn)程 → Nginx 代理能力 → Java 應(yīng)用狀態(tài)的全鏈路驗(yàn)證;
? Java 深度集成:利用 Spring Boot Actuator 提供標(biāo)準(zhǔn)化、可擴(kuò)展的健康契約;
? 生產(chǎn)敬畏:內(nèi)核參數(shù)、SELinux、防火墻、日志監(jiān)控等“隱形守護(hù)者”的必要性。

最后寄語(yǔ):真正的高可用,始于一次優(yōu)雅的故障切換,成于千百次靜默的守護(hù)。當(dāng)你下次看到 curl http://192.168.56.100 穩(wěn)穩(wěn)返回 200 OK,那背后是 Nginx 的穩(wěn)健、Keepalived 的睿智、Linux 內(nèi)核的精密,以及你親手寫下的每一行配置所凝聚的工程信仰。

以上就是基于Nginx+Keepalived實(shí)現(xiàn)高可用(主從切換)配置指南的詳細(xì)內(nèi)容,更多關(guān)于Nginx Keepalived高可用配置的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • nginx和Apache配置SSL證書的實(shí)現(xiàn)步驟

    nginx和Apache配置SSL證書的實(shí)現(xiàn)步驟

    SSL證書是一種數(shù)字證書,用于加密在網(wǎng)絡(luò)上發(fā)送的數(shù)據(jù)并保護(hù)敏感信息的安全性,本文主要介紹了nginx和Apache配置SSL證書的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • 詳解Nginx中HTTP的keepalive相關(guān)配置

    詳解Nginx中HTTP的keepalive相關(guān)配置

    這篇文章主要介紹了Nginx中HTTP的keepalive相關(guān)配置,以及Nginx的Httpd守護(hù)進(jìn)程相關(guān)的keepalive timeout配置,需要的朋友可以參考下
    2016-01-01
  • Ubuntu使用nginx搭建webdav文件服務(wù)器的詳細(xì)過(guò)程

    Ubuntu使用nginx搭建webdav文件服務(wù)器的詳細(xì)過(guò)程

    今天通過(guò)本文給大家分享Ubuntu使用nginx搭建webdav文件服務(wù)器的詳細(xì)過(guò)程,在這小編提示大家在安裝nginx時(shí)需要先安裝nginx-full,具體安裝方法跟隨小編一起通過(guò)本文學(xué)習(xí)下吧
    2021-05-05
  • nginx后端節(jié)點(diǎn)的健康檢查和nginx平滑升級(jí)方式

    nginx后端節(jié)點(diǎn)的健康檢查和nginx平滑升級(jí)方式

    本文介紹了Nginx反向代理的ngx_http_proxy_module和ngx_http_upstream_module模塊,以及淘寶開(kāi)發(fā)的nginx_upstream_check_module模塊,并介紹了Nginx平滑升級(jí)原理及實(shí)戰(zhàn)操作,最后總結(jié)了Nginx版本升級(jí)的方法
    2026-04-04
  • nginx+lua+redis實(shí)現(xiàn)限流的示例代碼

    nginx+lua+redis實(shí)現(xiàn)限流的示例代碼

    本文主要介紹了nginx+lua+redis實(shí)現(xiàn)限流的示例代碼,包括HttpRedis模塊、HttpRedis2Module模塊和lua-resty-redis庫(kù),具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-12-12
  • 針對(duì)OpenSSL安全漏洞調(diào)整Nginx服務(wù)器的方法

    針對(duì)OpenSSL安全漏洞調(diào)整Nginx服務(wù)器的方法

    這篇文章主要介紹了針對(duì)OpenSSL漏洞調(diào)整Nginx服務(wù)器的方法,2014年爆出的SSL安全漏洞震驚了全世界,需要的朋友可以參考下
    2015-06-06
  • Nginx靜態(tài)壓縮和代碼壓縮提高訪問(wèn)速度詳解

    Nginx靜態(tài)壓縮和代碼壓縮提高訪問(wèn)速度詳解

    Nginx提供靜態(tài)壓縮功能,對(duì)于比較大的文件,可以自動(dòng)默認(rèn)查找.gz后綴的壓縮包,下面這篇文章主要給大家介紹了關(guān)于Nginx靜態(tài)壓縮和代碼壓縮提高訪問(wèn)速度的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • Nginx介紹與安裝實(shí)踐指南

    Nginx介紹與安裝實(shí)踐指南

    Nginx是一個(gè)輕量級(jí)的、高性能的Web服務(wù)器/反向代理服務(wù)器及電子郵件(IMAP/POP3)代理服務(wù)器,本文給大家介紹Nginx介紹與安裝實(shí)踐指南,感興趣的朋友跟隨小編一起看看吧
    2026-05-05
  • Nginx?限流和流量控制的實(shí)現(xiàn)

    Nginx?限流和流量控制的實(shí)現(xiàn)

    Nginx通過(guò)limit_req和limit_conn模塊提供請(qǐng)求次數(shù)和并發(fā)連接數(shù)限制,防止服務(wù)器過(guò)載,本文就來(lái)介紹一下Nginx?限流和流量控制的實(shí)現(xiàn),感興趣的可以了解一下
    2024-09-09
  • 利用nginx解決跨域問(wèn)題的方法(以flask為例)

    利用nginx解決跨域問(wèn)題的方法(以flask為例)

    這篇文章主要介紹了利用nginx解決跨域問(wèn)題的方法,文中以flask為例給大家介紹的很詳細(xì),需要的朋友可以參考學(xué)習(xí),下面來(lái)一起看看吧。
    2017-02-02

最新評(píng)論

阿拉善盟| 兰溪市| 隆尧县| 资中县| 苍南县| 宜黄县| 阿拉善右旗| 全椒县| 泽库县| 新泰市| 乌审旗| 句容市| 阳东县| 龙江县| 安龙县| 巴林左旗| 大余县| 光山县| 天峻县| 新密市| 天祝| 乳源| 丰台区| 南昌市| 磐安县| 扎赉特旗| 金坛市| 澄城县| 广汉市| 万安县| 都江堰市| 浦城县| 武乡县| 江津市| 顺义区| 稻城县| 常山县| 彝良县| 泰顺县| 滨州市| 碌曲县|