Антипаттерн: кластер из трёх серверов под сайт-визитку
Заказчику нужен сайт-визитка: пять страниц, форма обратной связи, сотня-другая посетителей в сутки. А на созвоне по инфраструктуре кто-то из команды предлагает «сделать по-взрослому» — два веб-сервера за балансировщиком, реплика базы, keepalived на VRRP для отказоустойчивости. Звучит солидно, выглядит как забота о надёжности. На деле это классический антипаттерн: сложность, которая не решает ни одной реальной проблемы бизнеса, зато создаёт десяток новых. Разберём, почему так происходит, что именно ломается в такой архитектуре и как понять, сколько отказоустойчивости вам действительно нужно.
Содержание
- Как выглядит этот антипаттерн на практике
- Откуда берётся этот антипаттерн
- Рост сложности обслуживания: каждый компонент требует внимания
- Парадокс сложности: больше компонентов — не значит надёжнее
- Стоимость без реальной пользы для бизнеса
- Принцип соразмерности: когда сложная архитектура оправдана
- Что делать вместо кластера для простого сайта
Как выглядит этот антипаттерн на практике
Типичная схема, которую разворачивают под простой сайт «на вырост»: два фронтенд-сервера с одинаковым кодом, HAProxy или Nginx в роли балансировщика (часто ещё и с keepalived для отказоустойчивости самого балансировщика — то есть уже три единицы инфраструктуры вместо одной), отдельный сервер БД с потоковой репликацией на реплику. Итого — от трёх до пяти серверов там, где сайту хватило бы одного.
Конфиг балансировщика в таких проектах обычно выглядит примерно так:
# /etc/haproxy/haproxy.cfg
frontend web_front
bind *:80
default_backend web_back
backend web_back
balance roundrobin
server web1 10.0.0.11:80 check
server web2 10.0.0.12:80 check
А сверху — keepalived с VRRP для плавающего IP между двумя нодами балансировщика:
# /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 150
virtual_ipaddress {
10.0.0.10/24
}
}
И PostgreSQL с потоковой репликацией на отдельном сервере — то есть ещё один узел, за которым нужно следить отдельно от веб-серверов. Каждый из этих компонентов сам по себе — нормальная, проверенная технология. Проблема не в них, а в том, что весь этот стек собран под нагрузку, которую спокойно тянет один VPS с запасом по CPU и памяти в разы.
Откуда берётся этот антипаттерн
Причина почти никогда не техническая — она организационная и психологическая:
- Cargo cult из статей про «архитектуру уровня Netflix». Инженер читает разбор инфраструктуры крупного сервиса и переносит паттерн один в один, не сверяя его с реальной нагрузкой своего проекта.
- Резюме-driven development. Настроить HAProxy + keepalived + репликацию интереснее и «весомее» в портфолио, чем просто поднять один сервер и настроить бэкапы.
- Страх без измерения риска. «А вдруг сервер упадёт» — вопрос правильный, но на него не отвечают числами: сколько стоит бизнесу час простоя, как часто вообще падают современные VPS у надёжного провайдера. Без этих цифр решение принимается на эмоциях.
- Продавливание сверху вендорами и облаками. Managed-предложения по кластеризации подаются как «best practice по умолчанию», хотя по факту это опция для конкретного класса задач, а не универсальный стандарт — тот же механизм лежит в основе мифа про то, что Kubernetes нужен любому проекту.
- Путаница между «отказоустойчиво» и «сложно». Команда воспринимает количество серверов и компонентов как метрику надёжности сама по себе, забывая, что каждый лишний компонент — это ещё один узел, который может отказать.
Дальше разберём, что это стоит на практике — не в деньгах (тарифы у всех разные), а в человеко-часах и рисках.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверРост сложности обслуживания: каждый компонент требует внимания
Один сервер под визитку требует одного набора забот: обновления системы, бэкапы, мониторинг, TLS-сертификат. Три-пять серверов под ту же задачу требуют того же самого — но умноженного, плюс добавляется целый пласт задач, которых при одном сервере просто не существует:
- Синхронизация деплоя. Код нужно выкатывать на оба веб-сервера одинаково и одновременно, иначе пользователи по очереди получают то старую, то новую версию в зависимости от того, на какой бэкенд их отправил балансировщик.
- Health-check балансировщика. Нужно настроить и поддерживать проверки
checkв HAProxy, следить, чтобы они не давали ложных срабатываний — иначе балансировщик гоняет трафик на мёртвую ноду или, наоборот, выводит из ротации живой сервер. - VRRP-флаппинг. Keepalived между двумя балансировщиками может начать «моргать» плавающим IP при нестабильной сети между нодами — на ровном месте появляется симптом, которого при одном сервере физически быть не может.
- Репликация БД и её отставание. Реплика может отстать от мастера, и тогда часть запросов на чтение отдаёт устаревшие данные — для сайта-визитки это может значить, что форма обратной связи показывает «заявка отправлена», а в админке её ещё нет.
- TLS-сертификаты на нескольких хостах. Certbot и автопродление нужно настроить и проверить на каждом узле, который принимает HTTPS-трафик, а не в одном месте.
- Кворум и split-brain. Если для отказоустойчивости самого кластера используется что-то вроде Pacemaker/Corosync или Proxmox, вступает в силу требование к кворуму — нечётному числу узлов, и при разрыве сети между узлами система должна как-то решить, кто из них «главный», не разделившись на две живые половины одновременно.
- Логи и метрики теперь размазаны по нескольким серверам. Отладка любой проблемы — это уже не
journalctlна одной машине, а сопоставление логов балансировщика, обоих веб-серверов и обеих БД по времени.
Каждый из этих пунктов — не гипотетический риск, а рутинная задача, которая появляется в бэклоге команды и требует постоянного внимания. При этом ни один из них не добавляет сайту-визитке ни одного реального посетителя и не защищает от того единственного риска, который у такого сайта действительно есть — «сервер недоступен пару минут ночью, пока перезапускается служба».
Парадокс сложности: больше компонентов — не значит надёжнее
Здесь кроется контринтуитивный момент, который часто упускают, добавляя серверы «для надёжности». Доступность системы, собранной из нескольких независимых компонентов, работающих последовательно (каждый из которых должен быть жив, чтобы система в целом работала), считается перемножением вероятностей отказа каждого звена. Если у вас на пути запроса стоят балансировщик → веб-сервер → база данных, и каждый из них может отказать независимо, то суммарная вероятность отказа всей цепочки выше, чем у одного звена. Резервирование действительно поднимает доступность — но только если оно спроектировано и, что критичнее, эксплуатируется правильно. А правильная эксплуатация кластера — это сама по себе экспертиза, которой у команды, обслуживающей сайт-визитку, чаще всего просто нет и не должно быть.
На практике это выливается в конкретные истории, знакомые всем, кто работал с небольшими кластерами: балансировщик слал трафик на мёртвую ноду из-за неверно настроенного health-check и сайт «падал» не вопреки резервированию, а из-за него; две ноды на короткое время решали, что каждая из них главная, и раскалывали кластер split-brain'ом, одновременно записывая разные данные; забытый слот репликации не давал вовремя почистить WAL на мастере, диск заполнялся — и падал не только резервный узел, а всё вместе.
Ни один из этих сценариев не мог бы произойти на одном сервере — просто потому, что там нет второй ноды, с которой можно рассинхронизироваться, и нет балансировщика, который может ошибиться в выборе бэкенда. Кластер не убирает точки отказа, он добавляет новые — специфичные именно для распределённой системы, и статистически, если нагрузка не требует резервирования, простая система из одного компонента оказывается надёжнее в реальной эксплуатации, чем сложная система из пяти, за которой некому как следует следить.
Отдельно стоит вопрос человеческого фактора: чем больше движущихся частей в системе и чем реже команда с ней работает руками (потому что «всё само реплицируется»), тем выше шанс ошибки при том редком ручном вмешательстве, которое всё-таки понадобится — например, при аварийном переключении на резерв, которое не тренировали ни разу за год.
Стоимость без реальной пользы для бизнеса
С точки зрения бизнеса у сайта-визитки есть одна метрика, которая имеет значение: увидит ли посетитель страницу и дозвонится ли/дозаявится ли через форму. Кластер из трёх-пяти серверов не улучшает ни то, ни другое сравнительно с одним нормально настроенным сервером — разница в доступности между «один VPS с бэкапами и мониторингом» и «кластер с репликацией» для такой нагрузки статистически неразличима на горизонте, который волнует владельца сайта-визитки.
При этом расходы растут вполне ощутимо и без всякого выдуманного прайса это очевидно из самой архитектуры:
- Аренда трёх-пяти серверов вместо одного — кратный рост счёта за инфраструктуру, а не рост на проценты.
- Каждый сервер — это отдельный объект мониторинга, отдельные апдейты безопасности, отдельная поверхность атаки.
- Время администратора на настройку и поддержку кластера — это часы, которые можно было потратить на что-то, что реально приносит пользу бизнесу: скорость сайта, конверсию формы, SEO.
- Риск деградации из-за человеческой ошибки в конфиге кластера выше, чем риск деградации из-за отказа единственного сервера у вменяемого провайдера.
Сюда же ложится общая методика: если сопоставить это с уровнями отказоустойчивости и что каждый из них стоит, кластер на три ноды под сайт-визитку — это переход сразу на верхний уровень инвестиций при нулевом бизнес-требовании к RTO/RPO, которое бы этот уровень оправдывало. Деньги и время потрачены на защиту от риска, вероятность и цена которого никогда не были посчитаны.
Принцип соразмерности: когда сложная архитектура оправдана
Отказоустойчивая инфраструктура — не хорошая практика сама по себе, а ответ на конкретное требование бизнеса. Прежде чем строить кластер, стоит явно ответить на три вопроса.
Сколько стоит бизнесу час простоя. Для сайта-визитки без прямых продаж через сайт — обычно немного: несколько упущенных обращений, которые чаще всего перезвонят или напишут позже. Для интернет-магазина в пиковый сезон, платёжного шлюза или SaaS с SLA перед клиентами — это уже прямые деньги и репутация, и здесь расчёт может быстро оправдать резервирование.
Какая реальная нагрузка. Сайт-визитка на сотни-тысячи визитов в сутки — это нагрузка, которую современный VPS обрабатывает с большим запасом на одном ядре, без всякого горизонтального масштабирования. Балансировщик и вторая нода нужны не потому, что «так положено», а когда один сервер физически перестаёт справляться с потоком запросов — это отдельная, измеримая техническая причина, а не общий принцип.
Какие риски у бизнеса, если сайт временно недоступен. Витрина услуг, лендинг, блог — минимальный риск, восстановление за минуты из бэкапа приемлемо. Приём онлайн-платежей, запись к врачу, биллинг оператора связи — здесь недоступность бьёт напрямую по деньгам и доверию, и тогда отказоустойчивость становится не роскошью, а требованием.
Практический ориентир по классам задач:
| Тип проекта | Что оправдано |
|---|---|
| Сайт-визитка, лендинг, блог | Один сервер, автоматические бэкапы, внешний мониторинг (Uptime Kuma и алерты) |
| Интернет-магазин среднего размера | Один сервер с запасом по ресурсам + отдельный сервер под БД с регулярными бэкапами; резервный сервер «наготове», но не обязательно в горячем резерве |
| Проект с SLA перед клиентами, платежи, высоконагруженный сервис | Балансировщик + минимум два веб-узла + управляемая репликация БД, с продуманным и протестированным сценарием переключения |
| Финтех, медицина, инфраструктура с юридическими требованиями к доступности | Полноценный кластер с кворумом, географическим резервированием, регламентом failover — и отдельной командой, которая этим занимается |
Ключевая мысль: сложность инфраструктуры должна расти вслед за измеримым требованием — трафиком, который не помещается в один сервер, или ценой простоя, которая оправдывает инвестиции — а не вперёд него, «на всякий случай». Здесь тот же принцип соразмерности, что и в другом близком антипаттерне — покупке сервера с запасом на три года вперёд: избыточность, купленная заранее без расчёта, почти всегда обходится дороже, чем спокойное масштабирование по факту роста.
Что делать вместо кластера для простого сайта
Правильная отказоустойчивость для сайта-визитки — не отсутствие мер, а точно откалиброванные меры под реальный риск:
- Один сервер с запасом ресурсов — конфигурация, которая держит нагрузку с кратным запасом, а не впритык.
- Автоматические бэкапы вне самого сервера — снапшоты диска у провайдера плюс отдельная копия базы данных, желательно у другого поставщика хранения, а не только там же, где крутится сам сервер.
- Внешний мониторинг доступности — Uptime Kuma или аналог, который проверяет сайт снаружи и присылает алерт при падении, а не полагается на то, что кто-то заметит проблему вручную.
- Готовый, но не разворачиваемый заранее план восстановления — понятная инструкция или скрипт, как за 10-15 минут поднять сайт из бэкапа на новом сервере, если старый стал недоступен физически. Это дешевле в поддержке, чем постоянно работающий кластер, и покрывает тот же самый реальный риск.
- Пересмотр решения при росте. Как только нагрузка или бизнес-требования реально меняются — трафик перестаёт помещаться в один сервер, или сайт начинает принимать платежи напрямую — тогда и приходит время для балансировщика, второй ноды и репликации, уже осознанно и под конкретную метрику, а не «про запас».
Такой подход не выглядит так эффектно, как схема с тремя серверами и стрелочками между ними, зато он реально соответствует задаче, дешевле в деньгах и в человеческом времени, и — как ни парадоксально — статистически надёжнее, потому что в нём меньше узлов, которые могут подвести.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Разве резервный сервер — это не всегда полезно, даже для маленького сайта?
Полезно, если он снижает время простоя дешевле, чем вы теряете от самого простоя. Для сайта-визитки обычно дешевле держать актуальный бэкап и разворачивать новый сервер по требованию за 10-15 минут, чем оплачивать постоянно работающий резерв, который почти никогда не понадобится.
А что если сайт-визитка внезапно получит всплеск трафика — например, попадёт в новости?
Такой всплеск обычно снимается вертикальным апгрейдом сервера (больше CPU/RAM) за минуты, плюс кэшированием статики через CDN. Это быстрее и проще, чем заранее держать постоянный кластер под нагрузку, которая случается раз в несколько лет.
Чем плоха репликация БД сама по себе, если её настроить один раз и не трогать?
Репликацию нельзя «настроить и забыть» — она требует мониторинга отставания реплики, ротации WAL, регулярной проверки, что failover вообще сработает при реальной аварии. Непроверенный годами сценарий переключения часто ломается именно в момент, когда он нужен.
Как понять, что проекту уже пора переходить на кластер?
Смотрите на измеримые сигналы: сервер стабильно упирается в лимиты CPU/RAM под нормальной нагрузкой, простой начал измеримо стоить бизнесу денег, или перед клиентами есть договорной SLA. Пока таких сигналов нет — кластер решает проблему, которой не существует.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →