Задача клиента: маркетплейс на грани отказа
Весной 2026 года к нам в АйТи Фреш обратился B2B-маркетплейс ОптТорг из Нижнего Новгорода — платформа для оптовой торговли промышленными товарами. На площадке было зарегистрировано более 12 000 поставщиков и 45 000 закупщиков. Среднемесячная посещаемость — 500 000 уникальных визитов, а в периоды тендерных кампаний нагрузка возрастала вдвое.
Вся архитектура держалась на одном сервере nginx, который одновременно выполнял роль reverse proxy, SSL termination и статик-сервера. За ним стояли три бэкенд-сервера с приложением на Django, но единственный nginx превратился в классический single point of failure.
«В ноябре nginx упал на 47 минут. Мы потеряли сделки на 2,3 миллиона рублей — закупщики ушли к конкурентам и больше не вернулись» — технический директор ОптТорг.
За последний квартал было три инцидента: два из-за переполнения памяти при пиковых нагрузках и один из-за неудачного обновления конфигурации. Клиент понимал, что нужен полноценный балансировщик с отказоустойчивостью, но не имел экспертизы для его внедрения.
Аудит текущей инфраструктуры
Наши инженеры провели аудит и выявили следующие проблемы:
- Single point of failure — один nginx-сервер без резервирования
- Нет health checks — nginx продолжал направлять трафик на упавшие бэкенды
- SSL на каждом бэкенде — сертификаты дублировались, обновлялись вручную
- Нет sticky sessions — пользователи теряли сессию корзины при переключении между бэкендами
- Ручной деплой — обновление приложения требовало остановки nginx и 2–5 минут простоя
Исходная топология выглядела так:
# Текущая архитектура (до внедрения)
Интернет → 1× nginx (proxy + SSL) → 3× Django backend
→ 1× PostgreSQL
→ 1× Redis (сессии)
# IP-адреса
nginx: 185.120.30.10 (единственная точка входа)
backend1: 10.0.1.11
backend2: 10.0.1.12
backend3: 10.0.1.13
Целевая архитектура решения
Мы спроектировали архитектуру с двумя уровнями отказоустойчивости:
# Целевая архитектура
Интернет → Floating IP (VRRP)
├── HAProxy MASTER (haproxy1) — активный
└── HAProxy BACKUP (haproxy2) — горячий резерв
├── backend1 (10.0.1.11)
├── backend2 (10.0.1.12)
└── backend3 (10.0.1.13)
Ключевые решения:
- HAProxy вместо nginx — специализированный балансировщик с продвинутыми health checks, ACL и статистикой
- Keepalived с протоколом VRRP — автоматическое переключение floating IP между двумя HAProxy за 2–3 секунды
- SSL termination на уровне HAProxy — один сертификат, автоматическое обновление
- Sticky sessions через cookies — пользователь привязывается к конкретному бэкенду
Установка и настройка HAProxy
HAProxy — это высокопроизводительный TCP/HTTP-балансировщик, который используется такими компаниями как GitHub, Stack Overflow и Reddit. Мы установили его на двух серверах с Ubuntu 22.04 LTS для обеспечения резервирования.
Установка HAProxy 2.9 из официального репозитория
На обоих серверах (haproxy1 и haproxy2) мы выполнили идентичную установку:
# Добавляем официальный PPA HAProxy (версия 2.9 LTS)
sudo apt-get update
sudo apt-get install -y software-properties-common
sudo add-apt-repository -y ppa:vbernat/haproxy-2.9
sudo apt-get update
sudo apt-get install -y haproxy=2.9.*
# Проверяем установленную версию
haproxy -v
# HAProxy version 2.9.7-1ppa1~jammy
# Включаем автозапуск
sudo systemctl enable haproxy
# Разрешаем HAProxy привязываться к нелокальным IP (для floating IP)
echo 'net.ipv4.ip_nonlocal_bind = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Параметр ip_nonlocal_bind критически важен — без него HAProxy не сможет слушать на floating IP, который ещё не назначен интерфейсу (на backup-ноде).
Конфигурация глобальных параметров и дефолтов
Конфигурацию мы хранили в /etc/haproxy/haproxy.cfg. Начнём с секций global и defaults:
# /etc/haproxy/haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
# Оптимизация производительности
maxconn 50000
nbthread 4
# SSL: современные параметры
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
option forwardfor
option http-server-close
timeout connect 5s
timeout client 30s
timeout server 30s
timeout http-keep-alive 10s
timeout check 5s
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
Обратите внимание на maxconn 50000 — мы рассчитали это значение исходя из пиковых 500K визитов в месяц (примерно 300 одновременных соединений в штатном режиме и до 3000 в пик).
Frontend: SSL termination и маршрутизация
Frontend принимает все входящие соединения, терминирует SSL и маршрутизирует запросы:
# Frontend — приём входящего трафика
frontend ft_web
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/opttorg.ru.pem alpn h2,http/1.1
# Редирект HTTP → HTTPS
http-request redirect scheme https unless { ssl_fc }
# Заголовки безопасности
http-response set-header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
http-response set-header X-Frame-Options SAMEORIGIN
http-response set-header X-Content-Type-Options nosniff
# Логирование реального IP
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Real-IP %[src]
# ACL для маршрутизации
acl is_api path_beg /api/
acl is_static path_beg /static/ /media/
acl is_websocket hdr(Upgrade) -i WebSocket
# Маршруты
use_backend bk_api if is_api
use_backend bk_static if is_static
use_backend bk_websocket if is_websocket
default_backend bk_web
# Страница статистики HAProxy (доступ только из внутренней сети)
frontend ft_stats
bind *:8404
stats enable
stats uri /stats
stats refresh 10s
stats admin if TRUE
acl is_internal src 10.0.0.0/8 172.16.0.0/12
http-request deny unless is_internal
Для SSL мы подготовили единый PEM-файл, объединяющий сертификат и ключ:
# Подготовка SSL-сертификата для HAProxy
sudo mkdir -p /etc/haproxy/certs
# Объединяем сертификат, промежуточный CA и ключ в один файл
sudo cat /etc/letsencrypt/live/opttorg.ru/fullchain.pem \
/etc/letsencrypt/live/opttorg.ru/privkey.pem \
| sudo tee /etc/haproxy/certs/opttorg.ru.pem > /dev/null
sudo chmod 600 /etc/haproxy/certs/opttorg.ru.pem
Backend: health checks и sticky sessions
Самая важная часть конфигурации — бэкенды с продвинутыми проверками здоровья:
# Backend — основное веб-приложение
backend bk_web
balance roundrobin
option httpchk
http-check send meth GET uri /health ver HTTP/1.1 hdr Host opttorg.ru
http-check expect status 200
# Sticky sessions через cookie
cookie SERVERID insert indirect nocache httponly secure
# Бэкенд-серверы с health checks
server web1 10.0.1.11:8000 check inter 3s fall 3 rise 2 cookie web1 weight 100
server web2 10.0.1.12:8000 check inter 3s fall 3 rise 2 cookie web2 weight 100
server web3 10.0.1.13:8000 check inter 3s fall 3 rise 2 cookie web3 weight 100
# Сервер-резерв для graceful degradation
server backup 10.0.1.11:8000 check backup
# Backend — API (с более строгими таймаутами)
backend bk_api
balance leastconn
option httpchk
http-check send meth GET uri /api/health ver HTTP/1.1 hdr Host opttorg.ru
http-check expect status 200
timeout server 60s
retry-on conn-failure empty-response response-timeout
retries 2
server api1 10.0.1.11:8000 check inter 5s fall 2 rise 3
server api2 10.0.1.12:8000 check inter 5s fall 2 rise 3
server api3 10.0.1.13:8000 check inter 5s fall 2 rise 3
# Backend — статика (через nginx на бэкендах)
backend bk_static
balance roundrobin
option httpchk
http-check send meth HEAD uri /static/healthcheck.txt ver HTTP/1.1
http-check expect status 200
timeout server 10s
http-request set-header Cache-Control "public, max-age=86400"
server static1 10.0.1.11:80 check inter 10s
server static2 10.0.1.12:80 check inter 10s
server static3 10.0.1.13:80 check inter 10s
# Backend — WebSocket
backend bk_websocket
balance source
timeout tunnel 3600s
server ws1 10.0.1.11:8001 check inter 5s
server ws2 10.0.1.12:8001 check inter 5s
Разберём ключевые параметры health checks:
- inter 3s — проверка здоровья каждые 3 секунды
- fall 3 — сервер считается упавшим после 3 неудачных проверок (9 секунд)
- rise 2 — сервер возвращается после 2 успешных проверок (6 секунд)
- cookie SERVERID — HAProxy ставит cookie с ID бэкенда, обеспечивая sticky sessions
Для API-бэкенда мы выбрали алгоритм leastconn вместо roundrobin, так как API-запросы имели разную длительность (от 50ms для каталога до 5s для генерации отчётов).
Keepalived: автоматический failover через VRRP
HAProxy сам по себе не обеспечивает отказоустойчивость балансировщика. Если единственный HAProxy упадёт, ситуация будет ещё хуже, чем с nginx — ведь за ним вся инфраструктура. Поэтому мы развернули два HAProxy-сервера и связали их через Keepalived с протоколом VRRP.
Принцип работы VRRP и floating IP
VRRP (Virtual Router Redundancy Protocol) — протокол, позволяющий нескольким серверам делить один виртуальный IP-адрес. В любой момент времени IP принадлежит только одному серверу (MASTER). Если MASTER перестаёт отправлять heartbeat-пакеты, BACKUP забирает IP себе за 2–3 секунды.
# Установка Keepalived на обоих серверах
sudo apt-get install -y keepalived
# Проверяем версию
keepalived --version
# Keepalived v2.2.8
В облаке провайдера клиента мы заказали дополнительный IP-адрес 185.120.30.100 — он станет floating IP, который DNS-записи opttorg.ru будут указывать.
Конфигурация Keepalived на MASTER-ноде
Конфигурация на первом сервере (haproxy1, 185.120.30.11):
# /etc/keepalived/keepalived.conf на haproxy1 (MASTER)
global_defs {
router_id haproxy1
script_user root
enable_script_security
}
# Скрипт проверки HAProxy
vrrp_script check_haproxy {
script "/usr/bin/killall -0 haproxy"
interval 2
weight -20
fall 3
rise 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 110
advert_int 1
authentication {
auth_type PASS
auth_pass S3cureVRRP!key
}
virtual_ipaddress {
185.120.30.100/24 dev eth0
}
track_script {
check_haproxy
}
# Уведомление при смене состояния
notify_master "/etc/keepalived/notify.sh MASTER"
notify_backup "/etc/keepalived/notify.sh BACKUP"
notify_fault "/etc/keepalived/notify.sh FAULT"
}
Обратите внимание на скрипт check_haproxy: команда killall -0 haproxy проверяет, запущен ли процесс HAProxy. Если процесс мёртв, weight -20 снижает приоритет ноды на 20 пунктов, что приводит к переключению IP на BACKUP.
Конфигурация BACKUP-ноды и скрипт уведомлений
На втором сервере (haproxy2, 185.120.30.12) конфигурация почти идентична, но с другим приоритетом:
# /etc/keepalived/keepalived.conf на haproxy2 (BACKUP)
global_defs {
router_id haproxy2
script_user root
enable_script_security
}
vrrp_script check_haproxy {
script "/usr/bin/killall -0 haproxy"
interval 2
weight -20
fall 3
rise 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass S3cureVRRP!key
}
virtual_ipaddress {
185.120.30.100/24 dev eth0
}
track_script {
check_haproxy
}
notify_master "/etc/keepalived/notify.sh MASTER"
notify_backup "/etc/keepalived/notify.sh BACKUP"
notify_fault "/etc/keepalived/notify.sh FAULT"
}
Скрипт уведомлений отправляет алерт в Telegram при каждом переключении:
#!/bin/bash
# /etc/keepalived/notify.sh
STATE=$1
HOSTNAME=$(hostname)
DATE=$(date '+%Y-%m-%d %H:%M:%S')
BOT_TOKEN="YOUR_BOT_TOKEN"
CHAT_ID="YOUR_CHAT_ID"
MSG="⚠️ Keepalived: $HOSTNAME перешёл в состояние $STATE в $DATE"
curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
-d chat_id="${CHAT_ID}" \
-d text="${MSG}" \
-d parse_mode="HTML" > /dev/null 2>&1
logger "keepalived: переход в состояние $STATE"
# Делаем скрипт исполняемым и запускаем Keepalived
sudo chmod +x /etc/keepalived/notify.sh
sudo systemctl enable keepalived
sudo systemctl start keepalived
# Проверяем, что floating IP появился на MASTER
ip addr show eth0 | grep 185.120.30.100
# inet 185.120.30.100/24 scope global secondary eth0
Тестирование failover
Мы провели серию тестов переключения прямо в присутствии клиента:
# Тест 1: Остановка HAProxy на MASTER
# На haproxy1:
sudo systemctl stop haproxy
# На haproxy2 через 3-6 секунд:
ip addr show eth0 | grep 185.120.30.100
# inet 185.120.30.100/24 scope global secondary eth0 ✓ IP переехал
# Тест 2: Полная остановка MASTER
# На haproxy1:
sudo systemctl stop keepalived
# Тест 3: Возврат MASTER (preemption)
# На haproxy1:
sudo systemctl start haproxy
sudo systemctl start keepalived
# IP возвращается на MASTER через 1-2 секунды
# Непрерывный мониторинг во время тестов
# С отдельной машины:
while true; do
curl -s -o /dev/null -w "%{http_code} %{time_total}s\n" https://opttorg.ru/health
sleep 0.5
done
# 200 0.043s
# 200 0.041s
# 000 0.000s ← момент переключения (1-2 запроса)
# 200 0.052s
# 200 0.044s
Результат: переключение занимало 2–4 секунды, терялось не более 2–3 запросов. Для B2B-маркетплейса, где пользователи не обновляют страницу каждую секунду, это было приемлемо.
Мониторинг HAProxy и Keepalived
Балансировщик без мониторинга — как самолёт без приборной панели. Мы настроили несколько уровней наблюдения за кластером.
HAProxy Stats Page и Prometheus exporter
Встроенная страница статистики HAProxy доступна по порту 8404. Но для долгосрочного мониторинга мы развернули Prometheus exporter:
# Установка haproxy_exporter
wget https://github.com/prometheus/haproxy_exporter/releases/download/v0.15.0/haproxy_exporter-0.15.0.linux-amd64.tar.gz
tar xvf haproxy_exporter-0.15.0.linux-amd64.tar.gz
sudo mv haproxy_exporter-0.15.0.linux-amd64/haproxy_exporter /usr/local/bin/
# Systemd unit
sudo tee /etc/systemd/system/haproxy-exporter.service > /dev/null <<'EOF'
[Unit]
Description=HAProxy Exporter
After=network.target
[Service]
ExecStart=/usr/local/bin/haproxy_exporter \
--haproxy.scrape-uri="unix:/run/haproxy/admin.sock"
Restart=always
User=haproxy
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now haproxy-exporter
# Проверяем метрики
curl -s http://localhost:9101/metrics | head -20
В Grafana мы создали дашборд с ключевыми метриками:
- haproxy_frontend_current_sessions — текущие сессии
- haproxy_backend_http_responses_total — HTTP-ответы по кодам (2xx, 4xx, 5xx)
- haproxy_backend_response_time_average_seconds — средний response time
- haproxy_server_status — статус каждого бэкенда (UP/DOWN)
- haproxy_backend_retry_warnings_total — количество ретраев
Алерты в Prometheus и Telegram
Мы настроили алерты на критические ситуации:
# /etc/prometheus/rules/haproxy_alerts.yml
groups:
- name: haproxy
rules:
- alert: HAProxyBackendDown
expr: haproxy_server_status{state="UP"} == 0
for: 30s
labels:
severity: critical
annotations:
summary: "Backend {{ $labels.server }} в {{ $labels.proxy }} недоступен"
- alert: HAProxyHighErrorRate
expr: >
sum(rate(haproxy_backend_http_responses_total{code="5xx"}[5m]))
/
sum(rate(haproxy_backend_http_responses_total[5m])) > 0.05
for: 2m
labels:
severity: warning
annotations:
summary: "Доля 5xx ошибок превышает 5% (текущее: {{ $value | humanizePercentage }})"
- alert: HAProxyHighLatency
expr: haproxy_backend_response_time_average_seconds > 2
for: 5m
labels:
severity: warning
annotations:
summary: "Средний response time бэкенда {{ $labels.proxy }} > 2s"
- alert: KeepalivedFailover
expr: changes(node_systemd_unit_state{name="keepalived.service",state="active"}[5m]) > 0
labels:
severity: critical
annotations:
summary: "Keepalived failover произошёл на {{ $labels.instance }}"
Zero-downtime deploy через HAProxy
Одной из ключевых проблем клиента был простой при деплое. Раньше обновление приложения на трёх серверах занимало 5–10 минут с полным отключением трафика. Мы реализовали rolling deploy через управление HAProxy.
Скрипт rolling deploy
Деплой происходил поочерёдно: сервер выводился из балансировки, обновлялся, проходил health check и возвращался в строй:
#!/bin/bash
# /opt/scripts/rolling-deploy.sh
SERVERS=("web1" "web2" "web3")
BACKEND="bk_web"
HAPROXY_SOCKET="/run/haproxy/admin.sock"
HEALTH_URL="http://localhost:8000/health"
APP_DIR="/opt/opttorg"
for server in "${SERVERS[@]}"; do
echo "=== Деплой на $server ==="
# 1. Выводим сервер из балансировки (drain mode)
echo "disable server ${BACKEND}/${server}" | socat stdio "$HAPROXY_SOCKET"
echo "[$(date)] $server выведен из балансировки"
# 2. Ждём завершения текущих соединений (max 30 секунд)
echo "set server ${BACKEND}/${server} state drain" | socat stdio "$HAPROXY_SOCKET"
sleep 10
# 3. Обновляем приложение через SSH
ssh deploy@${server}.internal "cd $APP_DIR && \
git pull origin main && \
source venv/bin/activate && \
pip install -r requirements.txt --quiet && \
python manage.py migrate --noinput && \
sudo systemctl restart gunicorn"
# 4. Ждём, пока health check пройдёт
echo "Ожидаем готовность $server..."
for i in $(seq 1 30); do
HTTP_CODE=$(ssh deploy@${server}.internal "curl -s -o /dev/null -w '%{http_code}' $HEALTH_URL")
if [ "$HTTP_CODE" == "200" ]; then
echo "$server готов (попытка $i)"
break
fi
sleep 2
done
# 5. Возвращаем в балансировку
echo "enable server ${BACKEND}/${server}" | socat stdio "$HAPROXY_SOCKET"
echo "set server ${BACKEND}/${server} state ready" | socat stdio "$HAPROXY_SOCKET"
echo "[$(date)] $server возвращён в балансировку"
# 6. Пауза перед следующим сервером
sleep 5
done
echo "=== Деплой завершён на всех серверах ==="
Обновление конфигурации HAProxy без простоя
HAProxy поддерживает горячую перезагрузку конфигурации через механизм -sf (seamless reload):
# Проверяем новую конфигурацию (обязательно перед reload!)
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
# Configuration file is valid
# Горячая перезагрузка без потери соединений
sudo systemctl reload haproxy
# Или через команду напрямую (для старых систем)
sudo haproxy -f /etc/haproxy/haproxy.cfg -sf $(cat /run/haproxy.pid)
# Проверяем, что перезагрузка прошла
sudo journalctl -u haproxy -n 5 --no-pager
# haproxy[4521]: Proxy ft_web started.
# haproxy[4521]: Proxy bk_web started.
При reload HAProxy запускает новый процесс, который принимает новые соединения, а старый процесс дообрабатывает существующие — ни одно соединение не теряется.
Оптимизация производительности и безопасность
После базовой настройки наши специалисты провели тонкую оптимизацию для конкретных нагрузок маркетплейса.
Rate limiting и защита от DDoS
HAProxy позволяет реализовать rate limiting без внешних модулей:
# Добавляем в frontend ft_web
frontend ft_web
# ... (предыдущая конфигурация)
# Stick table для подсчёта запросов по IP
stick-table type ip size 200k expire 30s store http_req_rate(10s),conn_cur
# Отслеживаем запросы
http-request track-sc0 src
# Лимит: 100 запросов за 10 секунд с одного IP
http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }
# Лимит одновременных соединений: 50 с одного IP
http-request deny deny_status 429 if { src_conn_cur ge 50 }
# Тарпит для подозрительных запросов (замедление ответа)
http-request tarpit if { sc_http_req_rate(0) gt 200 }
timeout tarpit 5s
Оптимизация системных параметров ядра
Для обработки большого количества соединений мы настроили параметры ядра Linux:
# /etc/sysctl.d/99-haproxy.conf
# Увеличиваем лимиты TCP-соединений
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.core.netdev_max_backlog = 65535
# Быстрая утилизация TIME_WAIT соединений
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
# Расширяем диапазон эфемерных портов
net.ipv4.ip_local_port_range = 1024 65535
# Увеличиваем буферы
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 87380 16777216
# Keep-alive
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_keepalive_probes = 3
# Применяем параметры
sudo sysctl --system
# Увеличиваем лимит файловых дескрипторов для HAProxy
sudo tee /etc/security/limits.d/haproxy.conf > /dev/null <<'EOF'
haproxy soft nofile 131072
haproxy hard nofile 131072
EOF
# Дополнительно в systemd unit
sudo mkdir -p /etc/systemd/system/haproxy.service.d
sudo tee /etc/systemd/system/haproxy.service.d/limits.conf > /dev/null <<'EOF'
[Service]
LimitNOFILE=131072
EOF
sudo systemctl daemon-reload
sudo systemctl restart haproxy
Результаты внедрения
Проект был завершён за 5 рабочих дней. Вот что изменилось для маркетплейса ОптТорг после внедрения HAProxy и Keepalived специалистами АйТи Фреш:
| Метрика | До внедрения | После внедрения |
|---|
| Uptime за квартал | 99.2% (3 инцидента) | 99.98% (0 инцидентов) |
| Время failover | 5–47 минут (ручное) | 2–4 секунды (автоматическое) |
| Время деплоя | 5–10 минут с даунтаймом | 3 минуты без даунтайма |
| Средний response time | 380 мс | 210 мс (балансировка нагрузки) |
| Потерянные запросы при отказе | Все (до ручного восстановления) | 2–3 запроса за 2 секунды |
| Мониторинг бэкендов | Отсутствовал | Real-time в Grafana + алерты |
Через месяц после внедрения произошёл реальный инцидент — на MASTER-сервере вышел из строя сетевой интерфейс. Keepalived переключил floating IP на BACKUP за 3 секунды. Клиент узнал об инциденте только из Telegram-уведомления — пользователи ничего не заметили.
«Раньше каждый деплой — это стресс. Сейчас мы деплоим по три раза в день и спим спокойно. HAProxy + Keepalived — лучшая инвестиция за год» — CTO ОптТорг.