/
/
Отказоустойчивость интернет-магазина

Развитие отказоустойчивой инфраструктуры крупного интернет-магазина

О клиенте

Клиент управляет крупным интернет-магазином на базе «1С-Битрикс». Проект интегрирован с 1С, поисковыми системами, товарными выгрузками и внутренними корпоративными системами. Работа сайта зависит не только от веб-приложения, но и от регулярных обменов данными, фоновых заданий, поисковой индексации и доступности базы данных.

Инженерная поддержка потребовалась из-за роста нагрузки и сложности инфраструктуры. Отдельные серверы и механизмы резервирования уже существовали, но сама система требовала постоянного анализа: нужно было снижать время ответа, устранять аварии, масштабировать веб- и database-уровни и вводить новые серверы без длительной остановки сайта.

Исходная ситуация

Работа началась с аудита существующей инфраструктуры. На тот момент проект размещался на нескольких виртуальных серверах. Две веб-ноды использовались прежде всего для отказоустойчивости, но возможности архитектуры по распределению нагрузки были ограничены. Ресурсы серверов заметно потреблялись уже при обычной работе, а во время всплесков нагрузка на одну из нод доходила до высоких значений.

Клиент рассматривал переход на выделенные серверы и хотел понимать, какую конфигурацию выбрать, как сохранить резервную ноду и как выполнить перенос с минимальным простоем. Требовалось одновременно решить несколько связанных задач: повысить производительность, сохранить работоспособность обменов с 1С, организовать резервное копирование и не потерять возможность быстрого переключения при отказе.

По мере развития проекта инфраструктура становилась сложнее. Появлялись новые веб-ноды, реплики базы данных, балансировщики, технические серверы, Redis, средства защиты и дополнительные механизмы мониторинга. Поддержка постепенно перешла от первичного переноса к постоянному развитию распределенной системы.

Какие проблемы мы обнаружили

Архитектура обеспечивала резервирование, но не всегда эффективно распределяла нагрузку
Несколько серверов сами по себе не гарантировали масштабирование. Часть компонентов использовалась в режиме горячего или холодного резерва, а основная нагрузка продолжала концентрироваться на отдельных узлах.

При этом простое распределение записи между несколькими серверами MySQL создавало риск рассинхронизации. Поэтому на уровне базы данных нельзя было механически включить несколько активных мастеров и считать задачу отказоустойчивости решенной.

Для каждого расширения инфраструктуры требовалось отдельно определять роль новой ноды: активная обработка трафика, резерв, реплика для чтения, источник резервных копий или технический сервер.
Высокое время ответа не имело одной причины
Клиент регулярно фиксировал рост времени ответа, ошибки 502 и 504, увеличение Load Average и исчерпание лимитов Apache. В отдельных случаях сайт становился практически недоступен.

Причины различались. Нагрузку мог создавать зависший процесс веб-сервера, неоптимальная конфигурация Apache, обработка статических файлов через PHP, фоновые задачи, тяжелые запросы к базе или большое количество одновременных соединений.

Из-за этого увеличение процессорных ресурсов не всегда решало проблему. Например, повышенная нагрузка на балансировщик в одном из случаев оказалась следствием зависшего процесса Nginx, а не нехватки мощности виртуальной машины.
Веб-уровень выполнял лишнюю работу
Часть статических файлов и композитного кеша проходила через Apache и PHP, хотя могла отдаваться непосредственно через Nginx. Между балансировщиком и веб-серверами сохранялась лишняя работа с шифрованием.

Конфигурация PHP и Apache включала неиспользуемые модули и параметры, не соответствовавшие реальному количеству рабочих процессов. Это увеличивало потребление ресурсов и повышало вероятность достижения лимитов при всплесках трафика.
База данных оставалась одной из основных точек риска
По мере роста проекта возникали остановки MySQL, отставание реплик, нехватка соединений и высокая нагрузка на master-сервер. Некоторые запросы требовали дополнительных индексов. Временные таблицы и буферы были настроены без достаточной привязки к реальной нагрузке.

Резервные копии базы также нельзя было выполнять без учета нагрузки на основной сервер. Для этого требовались отдельные реплики и регулярная проверка не только факта создания копии, но и ее актуальности.
Синхронизация файлов усложняла распределенную архитектуру
Несколько веб-нод должны были работать с одинаковым набором файлов. Для синхронизации использовался lsyncd, но этот механизм оставался чувствительным к разрывам соединения и конфликтам при одновременном изменении данных.

При вводе новых серверов требовалось вручную контролировать направление синхронизации, актуальность файлов и момент включения новой ноды. Ошибка могла привести к распространению устаревших или нежелательных данных на рабочие серверы.

В дальнейшем клиент рассматривал переход к объектному хранилищу, чтобы сократить зависимость от прямой синхронизации файлов между нодами.
Рост инфраструктуры увеличивал сложность изменений
Добавление новой веб-ноды или реплики базы затрагивало балансировку, DNS, cron-задачи, FTP-доступ, обмены с 1С, мониторинг и синхронизацию файлов.

Переключение нельзя было рассматривать как простое копирование сервера. Требовалось выбрать окно между рабочим временем и ночными обменами, подготовить возможность отката, проверить новую ноду и только после этого включать ее в продуктивную схему.
Ресурсы серверов распределялись неравномерно
Со временем отдельные узлы столкнулись с нехваткой дискового пространства, а другие обладали более подходящими процессорами или объемом памяти.

Возникла задача ротации контейнеров: веб-серверы требовалось перенести на машины с более емкими SSD, а master базы данных — на сервер с более производительным процессором. Такие изменения нужно было выполнять без одновременной остановки всех компонентов.
Доступность требовала постоянного наблюдения
В материалах проекта зафиксировано большое количество сигналов мониторинга: недоступность сайтов, остановка Apache и MySQL, отставание репликации, ошибки резервного копирования, нехватка места и рост числа соединений.

Проблемой был не отдельный тип аварии, а широкий набор зависимых компонентов. Без централизованного мониторинга диагностика начиналась бы только после жалобы пользователей.

Что было сделано

1
Провели аудит и спроектировали целевую архитектуру
Существующие серверы подключили к мониторингу и собрали данные по нагрузке на процессоры, оперативную память и дисковое пространство. Текущую конфигурацию описали в технической документации.

На основании измерений сформировали требования к выделенным серверам, дисковой подсистеме и резерву ресурсов. Для данных и базы были рекомендованы SSD в RAID1, для локальных резервных копий — отдельные диски.

Архитектуру разделили на веб-уровень и уровень базы данных. Для базы предусмотрели master-slave-репликацию, чтобы использовать реплику для резервного копирования и восстановления без дополнительной нагрузки на основной сервер.
2
Перенесли проект на новую инфраструктуру
Новые серверы настраивали параллельно с действующими. Сначала создавали контейнеры и переносили копии данных, затем проверяли работу сайта и только после этого выполняли переключение.

Для объединения выделенных и виртуальных серверов была организована внутренняя сеть. Балансировщик использовался как единая точка входа и позволял подключать новую ноду без изменения внешней логики доступа к сайту.

Перенос выполнялся поэтапно, с учетом периодов обмена с 1С и допустимого окна работ. Старые серверы некоторое время сохранялись в качестве возможности отката.
3
Оптимизировали веб-контур
Была пересмотрена конфигурация PHP, Apache и Nginx. Неиспользуемые модули отключили, количество процессов и соединений привели в соответствие с ресурсами серверов.

Статические файлы и композитный кеш настроили на отдачу средствами Nginx, без лишнего прохождения через PHP. Обработку SSL сосредоточили на балансировщике, чтобы не выполнять повторное шифрование внутри серверного контура.

Для сессий внедрялось хранение в Memcached, а позднее — Redis. Это уменьшало зависимость веб-нод от локального состояния и снижало часть нагрузки на базу данных.
4
Развивали кластер базы данных
По мере роста нагрузки вводились новые серверы и реплики MySQL. Репликацию контролировали через мониторинг, проверяли отставание и состояние slave-узлов.

Настройки соединений, буферов и временных таблиц корректировались с учетом количества PHP-процессов и доступной памяти. Для тяжелых запросов добавлялись необходимые индексы.

При переносе master-сервера сначала разворачивали новую реплику, дожидались синхронизации и только затем выполняли переключение. Использование ProxySQL позволило менять состав database-кластера и перенаправлять соединения с минимальным простоем.
5
Масштабировали веб-уровень
В инфраструктуру последовательно вводились дополнительные веб-ноды. Перед подключением на них переносили актуальную копию сайта, настраивали доступы, cron-задачи, синхронизацию файлов и мониторинг.

После проверки сервер добавляли в балансировку. Старую ноду отключали не сразу, чтобы сохранить возможность быстрого возврата в случае проблем.

Для отдельных сценариев настраивали принудительное направление запросов на конкретную ноду. Это позволяло тестировать новый сервер на ограниченной части трафика до полноценного ввода.
6
Перестроили работу с техническими задачами и обменами
Для фоновых операций и обменов был выделен отдельный технический сервер. На него перенесли FTP-доступ, cron-задачи и процессы синхронизации, которые раньше выполнялись на одной из веб-нод.

Такое разделение уменьшило влияние служебных операций на обработку пользовательского трафика. Веб-ноды стали выполнять более однородную роль, а технические обмены получили отдельный контур.
7
Организовали резервное копирование и восстановление
Для контейнеров и баз данных настроили регулярное резервное копирование. Копии хранились как локально, так и на удаленной стороне.

Бэкапы базы выполнялись с реплик, чтобы не создавать дополнительную нагрузку на master. Состояние резервного копирования контролировалось мониторингом, а ошибки создания копий разбирались как эксплуатационные инциденты.

Копирование контейнеров позволяло восстанавливать не только данные, но и готовое серверное окружение на другом физическом узле.
8
Настроили мониторинг и обработку инцидентов
В Zabbix добавили контроль доступности сайтов, состояния веб-серверов, MySQL, репликации, дискового пространства и системных метрик.

Отдельно контролировались ошибки резервного копирования, фоновые процессы, синхронизация файлов, Redis, ElasticSearch и доступность внутренних адресов.

При росте нагрузки выполнялся разбор фактических запросов, процессов и соединений. Это позволяло отличать нехватку ресурсов от ошибок конфигурации, тяжелых запросов или некорректно работающего приложения.
9
Усилили защиту внешнего контура
Для проекта настраивались WAF и ModSecurity, блокировка подозрительных адресов, защита от DDoS и контроль вредоносной активности.

Правила фильтрации корректировались по результатам реального трафика, чтобы защитные механизмы не блокировали легитимные обмены, поисковых роботов и корпоративные интеграции.
Также закрывались служебные страницы и административные инструменты, которые не должны были быть доступны из внешней сети.
10
Перераспределили инфраструктуру между физическими серверами
По мере изменения нагрузки контейнеры переносили на серверы с более подходящими характеристиками. Веб-ноды размещали на машинах с большей дисковой емкостью, а master базы данных — на сервере с более производительным процессором и увеличенным объемом памяти.

Новые контейнеры создавали рядом с действующими. Для веб-нод использовали постепенное включение в балансировку, для базы — предварительное создание реплики и последующее переключение master.

Это позволило обновлять физическую основу проекта без одновременного переноса всей системы.

Результат

Инфраструктура проекта прошла путь от нескольких связанных серверов с ограниченным распределением нагрузки до развиваемой системы с отдельными веб-, database- и техническими контурами.

веб-нагрузка была распределена между несколькими нодами
появились резервные и дополнительные реплики базы данных
переключение database-узлов стало выполняться через ProxySQL
новые серверы можно было вводить с предварительным тестированием и возможностью отката
статические файлы и кеш стали обрабатываться без лишнего участия PHP
сессии были вынесены из локального состояния веб-серверов
фоновые обмены отделили от пользовательского трафика
резервное копирование базы перенесли с master на реплики
состояние сайтов, серверов, репликации и бэкапов контролировалось централизованно
физические ресурсы можно было перераспределять без полной остановки проекта
сократилось время поиска причин аварий и деградации производительности
инфраструктура получила техническую документацию и последовательный план развития

Вывод

Проблемы проекта нельзя было устранить одним увеличением мощности серверов или добавлением резервной ноды. Производительность и доступность зависели от конфигурации веб-серверов, состояния базы данных, синхронизации файлов, фоновых обменов и порядка переключения компонентов.

Основным результатом стала не отдельная миграция, а формирование управляемой инфраструктуры. Новые узлы вводились по повторяемой схеме, нагрузка распределялась по ролям, а изменения выполнялись с мониторингом, проверкой и возможностью отката.

Смотрите другие
кейсы по Bitrix

    Error get alias

    Хотите передать
    свою инфраструктуру в надежные руки?

    Будем рады проконсультировать вас и обсудить проект.