Dağıtık mesajlaşma sistemleri (Apache Pulsar, Kafka, RabbitMQ Cluster vb.) söz konusu olduğunda “HA (High Availability)” kelimesi çok hızlı şekilde karmaşık yapılara evrilir, ekstra kontrol katmanları, consensus mekanizmaları, orchestration çözümleri, her şeyi kontrol eden bir “cluster manager”… Bu yaklaşımlar doğru olsa da her ortam için şart değildir.
Benim sahada en sık gördüğüm durum şudur:
İnsanlar HA için çok büyük bir yapı kuruyor ama asıl problem HA deği, doğru failover kararını verememek.
Çünkü HA sadece “yedeklilik” değildir – HA demek hizmetin gerçekten kullanılabilir kalması demektir.
Bu yazımda anlatacağım mimari tam da buraya odaklanıyor:
- Çok karmaşık cluster topology’si kurmadan,
- Basit ama kontrollü bir şekilde,
- Failover’u “servis çalışıyor” gibi yüzeysel sinyallerden çıkarıp,
- servisin arkasındaki gerçek kapasiteyi ölçerek karar vermek,
Ve bunu iki temel bileşenle yapmak;
- HAProxy → Load balancing + sağlık bilgisini üreten merkez
- Keepalived (VRRP) → VIP yönetimi + failover tetikleme
Bu yaklaşım neden önemli? (Sahadaki asıl problem)
Birçok kişi Keepalived’i şu mantıkla kullanır:
- VIP → MASTER node üzerinde durur
- MASTER’de HAProxy aktif mi? → Evet → VIP burada kalsın
- HAProxy down oldu → VIP BACKUP node’a geçsin
Buradaki kritik hata şudur:
HAProxy ayakta olabilir ama arka tarafta broker havuzu ölmüş olabilir.
Yani:
- keepalived “servis ayakta” zannediyor,
- ama client tarafında publish/consume başarısız,
- sistem kullanıcı gözüyle down ama sistemin monitoring’i “green”,
Bu en tehlikeli arızadır: silent failure.
Ben bunun etkisini özellikle messaging sistemlerinde çok gördüm;
- client timeout’ları başlar,
- retry storm olur,
- connection sayıları patlar,
- broker load artar, daha fazla broker düşer,
- kısır döngü oluşur,
İşte bu mimari o yüzden güçlü, failover kararını “process var mı?” ile değil capacity var mı? ile veriyor.
Genel mimari tasarım: VIP + HAProxy + HA üzerinden failover
Bu mimarinin ana fikri sade;
- Client’lar tek bir adrese bağlanır: Virtual IP (VIP)
- VIP arkasında HAProxy vardır ve trafiği broker’lara dağıtır
- Broker health bilgisi HAProxy üzerinden toplanır
- Keepalived “failover” kararını HAProxy stats verisini okuyup verir
Bu mimariyle şunu başarmış olursunuz:
- Client config değişmez.
- Client tarafında “active broker bulma” karmaşası olmaz.
- Failover kararı ölçülebilir, objektif bir kritere bağlanır.
- Sistem “half-dead” olduğunda bile otomatik aksiyon alınır.
Keepalived burada ne yapıyor?
Keepalived’in rolü çok net;
- VIP’i iki node arasında taşımak
- VRRP ile “kim MASTER kim BACKUP” kararını vermek
- Failover’u tetiklemek için external script sonuçlarını izlemek
Bu noktada Keepalived’i sıradan bir VIP aracı olmaktan çıkaran şey:
track_script mekanizması ile failover’a servis katmanı zekâsı eklemek.
Sadece HAProxy çalışıyor mu kontrolü yetmez. track_script mantığı
Bu yapıda Keepalived iki ayrı kontrol script’i çalıştırır;
A) chk_haproxy
Bu script HAProxy process’i var mı / port dinliyor mu / basic health kontrol eder.
Bu check “minimum” kontrol. Çünkü HAProxy down olursa zaten VIP taşınmalı.
B) chk_pulsar
İşte burası mimarinin yıldız kısmı.
Bu script HAProxy’nin stats çıktısını okuyarak şu soruyu yanıtlar:
Backend havuzunda kaç broker DOWN durumda?
Yani Keepalived artık şuna bakıyor:
- “HAProxy yaşıyor mu?” değil,
- “HAProxy’nin arkasındaki servis gerçekten sağlıklı mı?”
5) HAProxy burada sadece LB değil — doğruluk kaynağı (source of truth)
Bu mimaride HAProxy bir load balancer gibi davranıyor ama aynı zamanda bir “hakem” gibi.
Sahada HA mimarilerinde en büyük problem:
- health check verisi dağınık olur
- herkes farklı yerden kontrol eder
- kimi
telnet 6650, kimicurl 8080, kimi “systemctl active” - sonuç: çelişkili sinyaller
HAProxy stats ise tek bir noktadan şunu söyler:
- Hangi broker UP?
- Hangi broker DOWN?
- Check rise/fall değerleriyle istikrarlı mı?
- Backend tamamen mi patladı?
Ben sahada mümkün olduğunca şöyle yapıyorum:
Failover kararında “tek truth kaynağı” seç ve sadece onu okut.
Burada truth kaynağı: HAProxy stats CSV.
6) check_pulsar.sh nasıl çalışır? (Failover’u belirleyen script)
Script’in ana fikri:
- HAProxy stats CSV çekilir
- belirli backend filtrelenir
$18=="DOWN"olanlar sayılır- eşik aşılırsa
exit 1
Örnek mantık:
- 3 broker var
MAX_DOWN=1
Bu şu demek:
- 0 broker DOWN → OK
- 1 broker DOWN → hala tolere edilebilir
- 2 broker DOWN → artık kapasite kritik, sistem degrade → FAILOVER
Bu yaklaşım sahada çok kıymetli çünkü:
- tek broker düşmesi failover’a sebep olmaz
- false positive azalır
- failover “gerekli olduğunda” olur
Failover bir çözüm değil, risktir. Gereksiz failover ortamı daha çok bozar.
Bu cümle HA tasarımında çok kritik bir prensip.
Failover kararı nasıl oluşuyor? (Keepalived’in iç mantığı)
Keepalived’te işler şu sırayla olur:
- script çalışır.
- script
exit 0döndürürse → node sağlıklı sayılır. - script
exit 1döndürürse → node’un priority’si düşürülür. - BACKUP node’un priority’si daha yüksek kalırsa,
- VIP diğer tarafa taşınır.
Bu sistemin güzelliği:
- network bazlı değil servis bazlı HA sağlaması
Ben bunu “VIP failover”dan ziyade şöyle adlandırıyorum:
“Service-aware failover”
Sahada ben olsam ekstra neler eklerdim? (Deneyim + pratik öneri)
Burayı özellikle eklemek istedim çünkü üretimde bu yapı çok iyi çalışsa da bazı noktalarda iyileştirme gerekir.
1) Failover kararına sadece DOWN sayısı değil, latency de eklenebilir
Bazı durumlarda broker UP görünür ama:
- thread pool doludur,
- response time uzamıştır,
- client retry yapar,
Bu yüzden ben genelde şunu severim:
- DOWN sayısı > threshold → fail,
- veya response time/queue aşırı artarsa → fail,
HAProxy stats üzerinden ayrıca şu metrikler de değerlendirilebilir:
qcur(current queue),scur(current sessions),rate(request rate),
Bunu script’e eklemek kolaydır.
2) “flapping” riskine dikkat
Failover’un en tehlikelisi VIP’in sürekli gidip gelmesi. Bunu önlemek için öneriler:
rise/falldeğerleri iyi ayarlanmalı- Keepalived’de
advert_intve script interval uyumlu olmalı MAX_DOWNagresif seçilmemeli- log ve telemetry ile failover sebebi izlenmeli
3 Script timeout / auth / erişim hatası durumları
Benim sahada en çok gördüğüm problem:
HAProxy stats çekilemiyor (curl timeout), script FAIL dönüyor, VIP gereksiz taşınıyor.
Burada iki yaklaşım var:
- (A) “Stats çekilemiyorsa failover tetikle” (agresif, riskli)
- (B) “Stats çekilemiyorsa ayrı alarm üret ama failover etme” (daha güvenli)
Ben genelde şunu yapıyorum:
- HAProxy down ise zaten
chk_haproxyfail eder - Stats erişim hatası varsa
chk_pulsarFAIL etmek yerine “WARN” yazmalı
Yani script’i şöyle güncellemek iyi olur:
- stats erişim hatası:
exit 0ama log’a ERROR yaz - gerçek DOWN broker sayısı eşiği aşarsa:
exit 1
4) Güvenlik: stats endpoint’ini koru
Stats endpoint’i kritik.
Öneriler:
- mümkünse sadece localhost’tan eriş,
- veya firewall ile sadece Keepalived node izinli olsun,
- auth password kesinlikle environment’ta plaintext bırakılmasın,
- basic auth yerine mTLS bile tercih edilebilir.
Örnek Mimari
Node01 (Datacenter / Site A)
- Node IP (Keepalived + HAProxy):
192.168.1.10(MASTER) - VIP (Client’ların bağlandığı adres):
192.168.1.11 - HAProxy Stats Bind:
192.168.1.10:9000 - Pulsar Broker’lar (Node01 tarafı):
192.168.1.48192.168.1.49192.168.1.50
Servis Portları
- Pulsar Broker:
6650 - HTTP API:
8080
Node02 (Datacenter / Site B)
- Node IP (Keepalived + HAProxy):
192.168.1.12(BACKUP) - VIP (Client’ların bağlandığı adres):
192.168.1.11 - HAProxy Stats Bind:
192.168.1.12:9000 - Pulsar Broker’lar (Node02 tarafı):
192.168.1.51192.168.1.52192.168.1.53
Servis Portları
- Pulsar Broker:
6650 - HTTP API:
8080
Node01 (MASTER) – Keepalived
Dosya: /etc/keepalived/keepalived.conf
vrrp_script chk_pulsar {
script "/usr/local/bin/check_pulsar.sh"
interval 2
weight 2
}
vrrp_script chk_haproxy {
script "/usr/local/bin/check_haproxy.sh"
interval 2
weight 2
}
vrrp_instance VI_PULSAR {
state MASTER
interface ens160
virtual_router_id 144
priority 101
advert_int 2
authentication {
auth_type PASS
auth_pass cluster_ha_2024
}
virtual_ipaddress {
192.168.1.11/24 dev ens160
}
unicast_src_ip 192.168.1.10
unicast_peer {
192.168.1.12
}
track_script {
chk_haproxy
chk_pulsar
}
}
Node01 – check_pulsar.sh
Dosya: /usr/local/bin/check_pulsar.sh
#!/bin/bash
#
# HAProxy backend health monitor via stats CSV
# Checks if >=2 brokers are DOWN, triggers failover (exit 1)
#
# Author : Kursad GUNES
# Version: 1.0
HAPROXY_STATS_URL="http://192.168.1.10:9000/haproxy?stats;csv"
AUTH="haproxy_admin:secure_pass_2024"
BACKEND="cluster01_backend_pulsar_6650"
MAX_DOWN=1 # fail if more than this many are DOWN
TIMEOUT=2
LOG_FILE="/var/log/check_haproxy_stats_down.log"
down_count=$(
curl -su "$AUTH" --max-time "$TIMEOUT" "$HAPROXY_STATS_URL" 2>/dev/null \
| awk -F',' -v backend="$BACKEND" '$1==backend && $2 !~ /BACKEND/ && $18=="DOWN" {c++} END{print c+0}'
)
if [ "$down_count" -gt "$MAX_DOWN" ]; then
echo "[$(date '+%F %T')] FAILOVER: $down_count servers DOWN" >> "$LOG_FILE"
exit 1
else
echo "[$(date '+%F %T')] OK: $down_count servers DOWN" >> "$LOG_FILE"
exit 0
fi
Not: Script’i çalıştırmadan önce;
chmod +x /usr/local/bin/check_pulsar.sh
Node01 – HAProxy
Dosya: /etc/haproxy/haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
maxconn 20000
user haproxy
group haproxy
defaults
log global
mode tcp
option dontlognull
option tcpka
timeout connect 10s
timeout client 1h
timeout server 1h
retries 3
frontend cluster01_frontend_pulsar_6650
bind 0.0.0.0:6650
mode tcp
option tcplog
default_backend cluster01_backend_pulsar_6650
frontend cluster01_frontend_8080
bind 0.0.0.0:8080
mode tcp
option tcplog
default_backend cluster01_backend_8080
# ON CLUSTER01 NODE: use the haproxy private ip
listen stats
bind 192.168.1.10:9000
mode http
no log
stats enable
stats uri /haproxy?stats
stats refresh 10s
stats auth haproxy_admin:secure_pass_2024
# ON CLUSTER01 NODE: use the 3 CLUSTER01 brokers
backend cluster01_backend_pulsar_6650
mode tcp
balance leastconn
option tcp-check
tcp-check connect port 6650
server b48 192.168.1.48:6650 check inter 3s fall 3 rise 2
server b49 192.168.1.49:6650 check inter 3s fall 3 rise 2
server b50 192.168.1.50:6650 check inter 3s fall 3 rise 2
backend cluster01_backend_8080
mode tcp
balance leastconn
option tcp-check
tcp-check connect port 8080
server b48 192.168.1.48:8080 check inter 3s fall 3 rise 2
server b49 192.168.1.49:8080 check inter 3s fall 3 rise 2
server b50 192.168.1.50:8080 check inter 3s fall 3 rise 2
Node02 (BACKUP) – Keepalived
Dosya: /etc/keepalived/keepalived.conf
vrrp_script chk_pulsar {
script "/usr/local/bin/check_pulsar.sh"
interval 2
weight 2
}
vrrp_script chk_haproxy {
script "/usr/local/bin/check_haproxy.sh"
interval 2
weight 2
}
vrrp_instance VI_PULSAR {
state BACKUP
interface ens160
virtual_router_id 144
priority 100
advert_int 2
authentication {
auth_type PASS
auth_pass cluster_ha_2024
}
virtual_ipaddress {
192.168.1.11/24 dev ens160
}
unicast_src_ip 192.168.1.12
unicast_peer {
192.168.1.10
}
track_script {
chk_haproxy
chk_pulsar
}
}
Node02 – check_pulsar.sh
Dosya: /usr/local/bin/check_pulsar.sh
#!/bin/bash
#
# HAProxy backend health monitor via stats CSV
# Checks if >=2 brokers are DOWN, triggers failover (exit 1)
#
# Author : Kursad GUNES
# Version: 1.0
HAPROXY_STATS_URL="http://192.168.1.12:9000/haproxy?stats;csv"
AUTH="haproxy_admin:secure_pass_2024"
BACKEND="cluster02_backend_pulsar_6650"
MAX_DOWN=1 # fail if more than this many are DOWN
TIMEOUT=2
LOG_FILE="/var/log/check_haproxy_stats_down.log"
down_count=$(
curl -su "$AUTH" --max-time "$TIMEOUT" "$HAPROXY_STATS_URL" 2>/dev/null \
| awk -F',' -v backend="$BACKEND" '$1==backend && $2 !~ /BACKEND/ && $18=="DOWN" {c++} END{print c+0}'
)
if [ "$down_count" -gt "$MAX_DOWN" ]; then
echo "[$(date '+%F %T')] FAILOVER: $down_count servers DOWN" >> "$LOG_FILE"
exit 1
else
echo "[$(date '+%F %T')] OK: $down_count servers DOWN" >> "$LOG_FILE"
exit 0
fi
Node02 – HAProxy
Dosya: /etc/haproxy/haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
maxconn 20000
user haproxy
group haproxy
defaults
log global
mode tcp
option dontlognull
option tcpka
timeout connect 10s
timeout client 1h
timeout server 1h
retries 3
frontend cluster02_frontend_pulsar_6650
bind 0.0.0.0:6650
mode tcp
option tcplog
default_backend cluster02_backend_pulsar_6650
frontend cluster02_frontend_8080
bind 0.0.0.0:8080
mode tcp
option tcplog
default_backend cluster02_backend_8080
# ON CLUSTER02 NODE: use the haproxy private ip
listen stats
bind 192.168.1.12:9000
mode http
no log
stats enable
stats uri /haproxy?stats
stats refresh 10s
stats auth haproxy_admin:secure_pass_2024
# ON CLUSTER02 NODE: use the 3 CLUSTER02 brokers
backend cluster02_backend_pulsar_6650
mode tcp
balance leastconn
option tcp-check
tcp-check connect port 6650
server b51 192.168.1.51:6650 check inter 3s fall 3 rise 2
server b52 192.168.1.52:6650 check inter 3s fall 3 rise 2
server b53 192.168.1.53:6650 check inter 3s fall 3 rise 2
backend cluster02_backend_8080
mode tcp
balance leastconn
option tcp-check
tcp-check connect port 8080
server b51 192.168.1.51:8080 check inter 3s fall 3 rise 2
server b52 192.168.1.52:8080 check inter 3s fall 3 rise 2
server b53 192.168.1.53:8080 check inter 3s fall 3 rise 2
(İsteğe bağlı ama öneririm) chk_haproxy.sh örneği
Eğer elinde yoksa, Keepalived’in chk_haproxy script’i için pratik bir örnek bırakıyorum:
Dosya: /usr/local/bin/check_haproxy.sh
#!/bin/bash
systemctl is-active --quiet haproxy
exit $?
chmod +x /usr/local/bin/check_haproxy.sh
Keepalived (Production) – Node01 (MASTER)
/etc/keepalived/keepalived.conf
global_defs {
router_id PULSAR_HA_NODE01
enable_script_security
script_user root
}
vrrp_script chk_haproxy {
script "/usr/local/bin/check_haproxy.sh"
interval 2
timeout 2
fall 2
rise 2
weight -20
}
vrrp_script chk_pulsar {
script "/usr/local/bin/check_pulsar.sh"
interval 2
timeout 3
fall 3
rise 3
weight -30
}
vrrp_instance VI_PULSAR {
state MASTER
interface ens160
virtual_router_id 144
priority 101
advert_int 1
authentication {
auth_type PASS
auth_pass cluster_ha_2024
}
virtual_ipaddress {
192.168.1.11/24 dev ens160
}
unicast_src_ip 192.168.1.10
unicast_peer {
192.168.1.12
}
track_script {
chk_haproxy
chk_pulsar
}
# Flapping azaltmak için:
# VIP bir kere Node02'ye geçtiyse hemen geri kapma
# (İstersen bunu kaldırabiliriz; bazı ortamlarda preempt istenir.)
nopreempt
# (opsiyonel) Bildirim scriptleri
notify_master "/usr/local/bin/vrrp_notify.sh MASTER"
notify_backup "/usr/local/bin/vrrp_notify.sh BACKUP"
notify_fault "/usr/local/bin/vrrp_notify.sh FAULT"
}
Neden böyle?
weight -20/-30: problem varsa priority düşer (failover tetiklenir)fall/rise: tek seferlik anlık hatalarda VIP zıplamasını engellernopreempt: VIP taşındıktan sonra hemen geri gelmesini engeller (çok faydalı)
Keepalived (Production) – Node02 (BACKUP)
/etc/keepalived/keepalived.conf
global_defs {
router_id PULSAR_HA_NODE02
enable_script_security
script_user root
}
vrrp_script chk_haproxy {
script "/usr/local/bin/check_haproxy.sh"
interval 2
timeout 2
fall 2
rise 2
weight -20
}
vrrp_script chk_pulsar {
script "/usr/local/bin/check_pulsar.sh"
interval 2
timeout 3
fall 3
rise 3
weight -30
}
vrrp_instance VI_PULSAR {
state BACKUP
interface ens160
virtual_router_id 144
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass cluster_ha_2024
}
virtual_ipaddress {
192.168.1.11/24 dev ens160
}
unicast_src_ip 192.168.1.12
unicast_peer {
192.168.1.10
}
track_script {
chk_haproxy
chk_pulsar
}
nopreempt
notify_master "/usr/local/bin/vrrp_notify.sh MASTER"
notify_backup "/usr/local/bin/vrrp_notify.sh BACKUP"
notify_fault "/usr/local/bin/vrrp_notify.sh FAULT"
}
chk_haproxy.sh (Production)
/usr/local/bin/check_haproxy.sh
#!/bin/bash
set -euo pipefail
# HAProxy aktif mi?
if systemctl is-active --quiet haproxy; then
exit 0
fi
exit 1
chmod +x /usr/local/bin/check_haproxy.sh
check_pulsar.sh (Production) – False Positive azaltılmış sürüm
Bu sürümde kritik farklar:
Stats endpoint’e ulaşılamıyorsa hemen failover ettirmiyoruz (en yaygın üretim kazası budur)
“Ardışık” kötü sonuç sayısını tutuyoruz (FAIL_STREAK)
Aynı anda iki kez çalışmayı engelliyoruz (flock)
Loglar daha okunur
Node01 için
/usr/local/bin/check_pulsar.sh
#!/bin/bash
set -euo pipefail
HAPROXY_STATS_URL="http://192.168.1.10:9000/haproxy?stats;csv"
AUTH="haproxy_admin:secure_pass_2024"
BACKEND="cluster01_backend_pulsar_6650"
MAX_DOWN=1 # 2 broker down olursa kritik (3 broker içinde)
TIMEOUT=2
LOG_FILE="/var/log/check_haproxy_stats_down.log"
# Üretimde çok işe yarar: ardışık hata olmadan failover yapma
STATE_DIR="/run/pulsar-ha"
STATE_FILE="${STATE_DIR}/pulsar_fail_streak"
FAIL_STREAK_TRIGGER=3 # 3 kez üst üste kötü -> failover
LOCK_FILE="/run/lock/check_pulsar.lock"
mkdir -p "$STATE_DIR"
log() {
echo "[$(date '+%F %T')] $*" >> "$LOG_FILE"
}
# Aynı anda paralel çalışmayı engelle
exec 200>"$LOCK_FILE"
flock -n 200 || exit 0
# Stats çek
csv="$(curl -su "$AUTH" --max-time "$TIMEOUT" -fsS "$HAPROXY_STATS_URL" 2>/dev/null || true)"
# Stats erişilemiyorsa: burada iki yaklaşım var.
# Üretimde genelde "failover etme, logla" daha güvenli.
if [[ -z "${csv}" ]]; then
log "WARN: Stats unreachable or empty. No failover (safe mode)."
exit 0
fi
down_count="$(echo "$csv" \
| awk -F',' -v backend="$BACKEND" '$1==backend && $2 !~ /BACKEND/ && $18=="DOWN" {c++} END{print c+0}')"
# Fail streak oku
streak=0
if [[ -f "$STATE_FILE" ]]; then
streak="$(cat "$STATE_FILE" 2>/dev/null || echo 0)"
fi
if [[ "$down_count" -gt "$MAX_DOWN" ]]; then
streak=$((streak + 1))
echo "$streak" > "$STATE_FILE"
log "BAD: backend=$BACKEND down_count=$down_count streak=$streak"
if [[ "$streak" -ge "$FAIL_STREAK_TRIGGER" ]]; then
log "FAILOVER: threshold exceeded. down_count=$down_count (MAX_DOWN=$MAX_DOWN) streak=$streak"
exit 1
fi
# Henüz streak dolmadı, failover tetikleme
exit 0
else
# Sağlıklıysa streak sıfırla
echo "0" > "$STATE_FILE"
log "OK: backend=$BACKEND down_count=$down_count"
exit 0
fi
Node02 için (sadece URL + BACKEND değişiyor)
/usr/local/bin/check_pulsar.sh
#!/bin/bash
set -euo pipefail
HAPROXY_STATS_URL="http://192.168.1.12:9000/haproxy?stats;csv"
AUTH="haproxy_admin:secure_pass_2024"
BACKEND="cluster02_backend_pulsar_6650"
MAX_DOWN=1
TIMEOUT=2
LOG_FILE="/var/log/check_haproxy_stats_down.log"
STATE_DIR="/run/pulsar-ha"
STATE_FILE="${STATE_DIR}/pulsar_fail_streak"
FAIL_STREAK_TRIGGER=3
LOCK_FILE="/run/lock/check_pulsar.lock"
mkdir -p "$STATE_DIR"
log() {
echo "[$(date '+%F %T')] $*" >> "$LOG_FILE"
}
exec 200>"$LOCK_FILE"
flock -n 200 || exit 0
csv="$(curl -su "$AUTH" --max-time "$TIMEOUT" -fsS "$HAPROXY_STATS_URL" 2>/dev/null || true)"
if [[ -z "${csv}" ]]; then
log "WARN: Stats unreachable or empty. No failover (safe mode)."
exit 0
fi
down_count="$(echo "$csv" \
| awk -F',' -v backend="$BACKEND" '$1==backend && $2 !~ /BACKEND/ && $18=="DOWN" {c++} END{print c+0}')"
streak=0
if [[ -f "$STATE_FILE" ]]; then
streak="$(cat "$STATE_FILE" 2>/dev/null || echo 0)"
fi
if [[ "$down_count" -gt "$MAX_DOWN" ]]; then
streak=$((streak + 1))
echo "$streak" > "$STATE_FILE"
log "BAD: backend=$BACKEND down_count=$down_count streak=$streak"
if [[ "$streak" -ge "$FAIL_STREAK_TRIGGER" ]]; then
log "FAILOVER: threshold exceeded. down_count=$down_count (MAX_DOWN=$MAX_DOWN) streak=$streak"
exit 1
fi
exit 0
else
echo "0" > "$STATE_FILE"
log "OK: backend=$BACKEND down_count=$down_count"
exit 0
fi
chmod +x /usr/local/bin/check_pulsar.sh
VRRP notify script (Opsiyonel ama çok faydalı)
VIP geçişlerini loglamak için:
/usr/local/bin/vrrp_notify.sh
#!/bin/bash
STATE="${1:-UNKNOWN}"
LOGGER_TAG="keepalived-vrrp"
logger -t "$LOGGER_TAG" "VRRP state changed to: $STATE on $(hostname -s)"
exit 0
chmod +x /usr/local/bin/vrrp_notify.sh
HAProxy Stats Güvenliği (Production önerisi)
Şu an stats 192.168.1.10:9000 ve 192.168.1.12:9000 üzerinden erişilebilir. Üretimde ideal olan:
Seçenek A (en iyisi): Stats sadece localhost
HAProxy’de:
listen stats
bind 127.0.0.1:9000
Ama burada script’in de http://127.0.0.1:9000/... kullanması gerekir.
Seçenek B: ACL ile sadece node IP’lerine izin
listen stats
bind 192.168.1.10:9000
mode http
acl allowed src 192.168.1.10 192.168.1.12
http-request deny if !allowed
stats enable
stats uri /haproxy?stats
stats auth haproxy_admin:secure_pass_2024
Uygulama / Test Komutları (Hızlı doğrulama)
Keepalived durum
systemctl status keepalived
ip a | grep 192.168.1.11
HAProxy stats test
curl -su haproxy_admin:secure_pass_2024 "http://192.168.1.10:9000/haproxy?stats;csv" | head
Script test
/usr/local/bin/check_pulsar.sh; echo $?
tail -n 50 /var/log/check_haproxy_stats_down.log
Failover simülasyonu
- Node01 tarafında 2 broker’ı DOWN durumuna düşür (servisi durdur / portu kapat)
- log’da
FAILOVER:satırlarını gör - VIP’nin Node02’ye geçtiğini doğrula