Нещодавно у клієнта production-база впала о 3:15 AM. Черговий прокинувся, але Wi-Fi глючив. Через 20 хвилин після логіну скрипт відновлення не спрацював через помилку в конфігурації. Downtime склав 45 хвилин — година простою обійшлася компанії в середньому $10,000, тож втратили $7,500 тільки на цьому інциденті. Автоматичний failover міг би скоротити це до 30 секунд — у 30-60 разів швидше за ручне перемикання. Але тільки якщо він налаштований правильно. Ми стикалися з кейсами, коли автоматика робила тільки гірше: split-brain, розходження даних, ручне відновлення на 4 години. Тому до налаштування failover потрібно підходити з розумінням підводних каменів.
Ми розробляємо та впроваджуємо автоматичний failover — систему, яка виявляє відмову основного сайту та перемикає трафік на резервний без участі людини. Завдання нетривіальне: потрібен захист від split-brain, хибних спрацьовувань, коректний порядок зупинки та запуску сервісів. Помилка тут небезпечніша за ручне перемикання.
Як працює захист від split-brain?
Splіt-brain виникає, коли обидва сайти вважають себе активними та одночасно приймають записи. Результат — розходження даних, яке потім складно reconcile. Класичний випадок: мережа між регіонами обірвалася на 30 секунд. DR-сайт promote-нув репліку, а primary залишився живим і продовжував приймати транзакції. Після відновлення отримали двох майстрів з різними даними.
Захист — кворум через зовнішній арбітр. Для PostgreSQL використовуємо Patronі з etcd, Consul або ZooKeeper. Для кластерів — witness node або STONITH (Shoot The Other Node In The Head) — гарантоване вимкнення ноди перед promote.
---
# patroni.yml — конфигурация автоматического failover
scope: pg-production
bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
# Максимальный лаг реплики, при котором она может стать мастером
maximum_lag_on_failover: 1048576 # 1 MB
# Синхронный режим: хотя бы одна реплика должна подтвердить запись
synchronous_mode: true
synchronous_mode_strict: false # false = не блокировать запись если нет реплик
postgresql:
use_pg_rewind: true # позволяет вернуть старый мастер как реплику
# Скрипт вызывается при смене роли
post_failover:
- name: notify_ops
command: /usr/local/bin/notify-failover.sh
---
Чому DNS failover не завжди рятує?
DNS failover через Route53 Health Check або Cloudflare Load Balancing — популярне рішення, але з серйозним недоліком: TTL кешування. Навіть при TTL=60 клієнти можуть тримати старий IP декілька хвилин. Для критичних додатків використовуємо Anycast (Cloudflare Argo, AWS Global Accelerator) — перемикання на мережевому рівні, минаючи DNS-кеш. Anycast дає час перемикання менше 10 секунд проти 60-300 секунд у DNS.
# terraform/route53-failover.tf
resource "aws_route53_health_check" "primary" {
fqdn = "app-primary.company.internal"
port = 443
type = "HTTPS"
resource_path = "/health"
failure_threshold = 3
request_interval = 10
tags = {
Name = "primary-health-check"
}
}
resource "aws_route53_record" "app_primary" {
zone_id = aws_route53_zone.main.zone_id
name = "app.company.com"
type = "A"
failover_routing_policy {
type = "PRIMARY"
}
health_check_id = aws_route53_health_check.primary.id
set_identifier = "primary"
ttl = 60
records = [var.primary_ip]
}
resource "aws_route53_record" "app_dr" {
zone_id = aws_route53_zone.main.zone_id
name = "app.company.com"
type = "A"
failover_routing_policy {
type = "SECONDARY"
}
set_identifier = "dr"
ttl = 60
records = [var.dr_ip]
} Як автоматизувати failover за допомогою AWS Lambda?
Для складних сценаріїв оркеструємо failover через Lambda, викликану EventBridge за CloudWatch алертом. Скрипт promote-ить Read Replica, оновлює конфіг в SSM, перезапускає ECS сервіси та перемикає Route53. Час виконання — близько 2 хвилин. Детальніше в документації AWS Lambda.
# lambda/failover-orchestrator.py
import boto3
import json
def lambda_handler(event, context):
""" Викликається EventBridge при алерті CloudWatch: DatabaseDown severity=critical duration=5m """
rds = boto3.client('rds', region_name='eu-central-1')
r53 = boto3.client('route53')
# Шаг 1: Promote RDS Read Replica в DR-регионе
response = rds.promote_read_replica(
DBInstanceIdentifier='prod-dr-replica',
BackupRetentionPeriod=7,
PreferredBackupWindow='03:00-04:00'
)
# Ждём, пока реплика стане standalone
waiter = rds.get_waiter('db_instance_available')
waiter.wait(DBInstanceIdentifier='prod-dr-replica')
# Шаг 2: Обновить application config через SSM Parameter Store
ssm = boto3.client('ssm', region_name='eu-west-1')
dr_endpoint = rds.describe_db_instances(
DBInstanceIdentifier='prod-dr-replica'
)['DBInstances'][0]['Endpoint']['Address']
ssm.put_parameter(
Name='/app/database/host',
Value=dr_endpoint,
Type='String',
Overwrite=True
)
# Шаг 3: Перезапустить ECS сервисы в DR-регионе с новым конфигом
ecs = boto3.client('ecs', region_name='eu-west-1')
ecs.update_service(
cluster='prod-dr',
service='app',
forceNewDeployment=True
)
# Шаг 4: Переключить Route53
# (вызов update_health_check или change_resource_record_sets)
return {'status': 'failover_initiated', 'dr_db': dr_endpoint} Як протестувати failover без ризику?
Періодично перевіряємо, що автоматика працює. Процес тестування складається з кроків:
- Відключаємо health check endpoint для primary-ресурсу.
- Переконуємося, що трафік переключився на DR-сайт (перевіряємо логи та метрики).
- Включаємо health check назад.
- Повертаємо primary в стрій та виконуємо switchback через
patronictl switchover.
Для Patroni використовуємо patronictl failover --master current-master --candidate replica-dr --force. Після кожного тестового failover обов'язково перевіряємо повернення в primary mode. Рекомендуємо проводити тести не рідше разу на квартал, а для критичних систем — щомісяця. Економія від впровадження failover може перевищувати $100,000 на рік за рахунок запобігання простоям.
Порівняння методів failover
| Метод | Час перемикання | Складність | Ризик split-brain |
|---|---|---|---|
| DNS failover (TTL=60) | 60-300 сек | Низька | Немає |
| Anycast (Global Accelerator) | <10 сек | Середня | Немає |
| BGP anycast | <1 сек | Висока | Так (потребує налаштування) |
| Patroni + etcd | <30 сек | Середня | Немає (кворум) |
Що входить в нашу роботу
- Аудит поточної інфраструктури та виявлення single points of failure
- Проектування архітектури failover (DNS/Anycast, БД, додатки)
- Налаштування Patroni, Route53, Lambda, Ansible
- Розробка runbook та процедури відкату
- Тестування сценаріїв: відмова primary, відмова репліки, відмова мережі
- Документація та передача знань вашій команді
Орієнтовні строки
| Складність | Компоненти | Строк |
|---|---|---|
| Базовий | DNS failover (Route53/Cloudflare) + 1 БД | 3–5 днів |
| Середній | Patroni + DNS + app layer, 2–3 сервіси | 1–2 тижні |
| Складний | Повна оркестрація (Lambda/Ansible), 10+ сервісів, тестування | 4–8 тижнів |
Вартість проекту обговорюється після аудиту. Отримайте консультацію з налаштування failover — зв'яжіться з нами для оцінки вашого проекту. Досвід наших інженерів — понад 10 років у продакшен-інфраструктурі. Замовте аудит вашої інфраструктури вже сьогодні.







