+------------------+
| Client App |
+--------+---------+
|
v
+--------+---------+
| Keepalived | VIP: 192.168.57.180
| (Master/Backup) |
+--------+---------+
|
+------------------------+------------------------+
| | |
v v v
+--------+--------+ +--------+--------+ +--------+--------+
| HAProxy 1 | | HAProxy 2 | | HAProxy N |
| 192.168.57.181 | | 192.168.57.179 | | ... |
+--------+--------+ +--------+--------+ +--------+--------+
| | |
+------------------------+------------------------+
|
+------------------------+------------------------+
| | |
v v v
+--------+--------+ +--------+--------+ +--------+--------+
| MyCat 1 | | MyCat 2 | | MyCat N |
| 192.168.57.181 | | 192.168.57.179 | | ... |
| Port 8066 | | Port 8066 | | Port 8066 |
+--------+--------+ +--------+--------+ +--------+--------+
| | |
+------------------------+------------------------+
|
+------------------------+------------------------+
| | |
v v v
+--------+--------+ +--------+--------+ +--------+--------+
| MySQL Shard 1 | | MySQL Shard 2 | | MySQL Shard N |
| (Master/Slave) | | (Master/Slave) | | (Master/Slave) |
+-----------------+ +-----------------+ +-----------------+
global
log 127.0.0.1 local0
maxconn 4096
chroot /usr/local/haproxy
user haproxy
group haproxy
daemon
pidfile /var/run/haproxy.pid
defaults
log global
option dontlognull
retries 3
option redispatch
maxconn 2000
timeout connect 5s
timeout client 30s
timeout server 30s
# 統計頁面 (VIP:48800)
listen admin_stats
bind 192.168.57.180:48800
mode http
option httplog
stats enable
stats uri /admin-status
stats auth admin:AdminPass123!
stats refresh 30s
# MyCat 負載均衡 (VIP:8098)
listen mycat_cluster
bind 192.168.57.180:8098
mode tcp
option tcplog
option tcp-check
balance roundrobin
default-server inter 5s rise 2 fall 3
server mycat_181 192.168.57.181:8066 check port 48700
server mycat_179 192.168.57.179:8066 check port 48700
timeout server 20s
## 安裝 xinetd
yum install -y xinetd
## /etc/xinetd.d/mycat_status
service mycat_status
{
flags = REUSE
socket_type = stream
port = 48700
wait = no
user = nobody
server = /usr/local/bin/mycat_status
log_on_failure += USERID
disable = no
}
## /usr/local/bin/mycat_status
#!/bin/bash
MYCAT_STATUS=$(/usr/local/mycat/bin/mycat status 2>/dev/null | grep -c 'running')
if [ $MYCAT_STATUS -eq 1 ]; then
echo -e "HTTP/1.1 200 OK\r\n"
exit 0
else
echo -e "HTTP/1.1 503 Service Unavailable\r\n"
exit 1
fi
## 權限與服務
chmod 755 /usr/local/bin/mycat_status
echo "mycat_status 48700/tcp" >> /etc/services
systemctl restart xinetd && systemctl enable xinetd
二、Keepalived 部署與配置 (雙節點 181/179)
1. 安裝 (源碼編譯)
global_defs { router_id LVS_MASTER_181 script_user root enable_script_security } vrrp_script chk_haproxy { script "/etc/keepalived/scripts/check_haproxy.sh" interval 2 weight 2 fall 3 rise 2 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 150 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.57.180/24 dev eth0 label eth0:VIP } track_script { chk_haproxy } notify_master "/etc/keepalived/scripts/notify_master.sh" notify_backup "/etc/keepalived/scripts/notify_backup.sh" notify_fault "/etc/keepalived/scripts/notify_fault.sh" notify_stop "/etc/keepalived/scripts/notify_stop.sh" }3. Backup 節點配置 (192.168.57.179) - 差異點
## /etc/keepalived/scripts/check_haproxy.sh #!/bin/bash if ! pidof haproxy >/dev/null; then systemctl start haproxy # 或 /usr/local/haproxy/sbin/start sleep 2 fi if ! pidof haproxy >/dev/null; then exit 1 fi exit 0 ## /etc/keepalived/scripts/notify_master.sh #!/bin/bash systemctl restart haproxy logger "Keepalived: Became MASTER, HAProxy restarted" ## /etc/keepalived/scripts/notify_backup.sh #!/bin/bash systemctl restart haproxy logger "Keepalived: Became BACKUP, HAProxy restarted" ## /etc/keepalived/scripts/notify_fault.sh #!/bin/bash logger "Keepalived: FAULT state" ## /etc/keepalived/scripts/notify_stop.sh #!/bin/bash logger "Keepalived: STOPPED" chmod +x /etc/keepalived/scripts/*.sh三、驗證與測試
- 統計頁面:
https://192.168.57.180:48800/admin-status(admin/AdminPass123!)- MyCat 連線測試:
mysql -h 192.168.57.180 -P 8098 -uuser -p- 故障切換測試:
- Master 上
systemctl stop keepalived→ VIP 漂移到 Backup- 客戶端連線無感知切換 (TCP 連線需重連,長連接應用需實現重試)
四、關鍵避坑指南
| 坑點 | 現象 | 解決 |
|---|---|---|
| 腳本權限 | Keepalived 無法執行通知腳本 | chmod +x 所有 .sh、shebang 行正確 #!/bin/bash |
| SELinux | VIP 綁定失敗、腳本執行被阻 | setenforce 0 或配置策略 |
| 防火牆 | VRRP 組播 (224.0.0.18) / VIP / HAProxy 端口不通 | 開放 VRRP、VIP、8098、48700、48800 |
| 網卡標識 | eth0 vs ens33 不匹配 | ip link 確認實際網卡名,配置文件統一 |
| 優先級抖動 | Master/Backup 頻繁切換 | 啟用 nopreempt、調大 advert_int、檢查腳本檢查邏輯 |
| HAProxy 重啟衝突 | notify 腳本並發重啟導致端口佔用 | 腳本加鎖、檢查進程狀態後再啟動 |
listenHAProxy (負載均衡) + Keepalived (VIP 漂移) + MyCat (分庫分表中間件) 構建了完整的讀寫分離、分片路由、高可用轉發三層架構。核心難點在於:健康檢查腳本可靠性、Keepalived 通知腳本與 HAProxy 協同重啟、VRRP 組播網絡環境、防火牆/SELinux 策略。生產部署必須經過完整故障注入測試,建立標準化運維手冊。