Контекст
Типовая ситуация зрелого магазина на коробочной платформе. Проект живёт несколько лет, за это время его дорабатывали разные подрядчики. Функциональность выросла за пределы того, что платформа предполагала, а правки вносились туда, где было быстрее, — включая файлы ядра.
Формально магазин работает. Практически — развитие остановилось: обновиться нельзя, потому что обновление затрёт правки; не обновляться тоже нельзя, потому что накапливаются уязвимости и несовместимости.
Проблема
Ядро изменено, и никто не знает где именно. Обновление платформы означает потерю неизвестного количества доработок. Список правок отсутствует.
Модули конфликтуют. Установлено больше расширений, чем используется. Часть из них переопределяет одни и те же участки. Порядок загрузки влияет на поведение — способ, которым отлаживать изменения крайне тяжело.
Бизнес-логика не помещается в модель платформы. Правила ценообразования, условия доставки или структура заказа отличаются от типовых настолько, что каждая доработка делается обходным путём.
Тестовой среды нет. Изменения проверяются на боевом магазине.
Ограничения
Ключевое ограничение миграции магазина — не техническое, а экономическое: поисковый трафик представляет накопленный за годы актив. Он не восстанавливается вложениями в разработку и теряется от одной ошибки в структуре адресов.
Второе ограничение — необратимость. После переключения DNS и начала приёма заказов на новой системе откат означает потерю заказов, оформленных в промежутке. Процедура отката должна быть подготовлена до переезда и учитывать это.
Диагностика
Инвентаризация правок. Файлы установленной платформы сравниваются с эталонной поставкой той же версии. Различия дают точный список изменённых мест. По каждому определяется, что именно правка делает и нужна ли она до сих пор. Среди таких находок часто бывает код, оставшийся от уже снятых задач.
Аудит модулей. По каждому расширению — используется ли оно, какие участки переопределяет, есть ли пересечения с другими.
Инвентаризация URL. Выгрузка всех индексируемых адресов из карты сайта, логов веб-сервера и панели вебмастера. Адреса ранжируются по трафику: страницы, приносящие основной поток, получают приоритет при проверке.
Профилирование данных. Количество товаров, категорий, клиентов, заказов; целостность связей; наличие записей-сирот. Расхождения находятся до переноса, а не в момент, когда каталог уже переехал.
Предлагаемая архитектура
Источник истины для каждого поля. Товар существует в магазине и в учётной системе. Остаток, цена, описание, статус заказа — по каждому полю фиксируется, какая система им управляет и в какую сторону идёт обмен. Без этого решения синхронизация превращается в перетирание данных туда-обратно.
Обмен через очередь. Интеграция с учётной системой не блокирует оформление заказа. Заказ принимается и ставится в очередь на отправку. Недоступность учётной системы даёт задержку синхронизации, а не потерянный заказ.
Слой совместимости URL. Карта соответствия старых адресов новым — отдельная сущность в новой системе, а не список правил в конфигурации веб-сервера. Она версионируется, покрывается тестами и позволяет проверить каждый значимый адрес автоматически.
Поэтапное переключение. Новая система разворачивается параллельно и наполняется данными. Проверка идёт на реальных данных до того, как на неё направлен трафик.
Реализация
Порядок работ определяется требованием обратимости на каждом шаге.
Сначала — тестовая среда, повторяющая рабочую систему, с копией боевых данных. Без неё дальнейшие шаги проверить негде.
Затем перенос данных: скрипты миграции пишутся идемпотентными, чтобы прогон можно было повторять многократно. Каждый прогон завершается отчётом сверки — количество сущностей по типам, целостность связей, контрольные примеры конкретных заказов и товаров, сверяемых вручную.
Карта редиректов формируется из инвентаризации URL. Для каждого адреса из выгрузки определяется новый адрес или причина, по которой страница исчезает. Автоматический тест проходит по списку и проверяет код ответа — постоянный редирект в правильное место.
Интеграция с учётной системой переносится последней и первое время работает в двух направлениях параллельно со старой, чтобы расхождение обнаружилось до переключения.
Переключение выполняется по письменному регламенту: последовательность шагов, ответственные, критерии успеха каждого шага, точка невозврата обозначена явно.
Надёжность и нештатные ситуации
- Заказ оформлен в момент переключения. Приём заказов на старой системе останавливается до переключения DNS, а не одновременно с ним. Промежуток закрывается страницей обслуживания, а не потерянными заказами.
- Товар удалён, но его страница в индексе. Для каждой удалённой страницы заранее выбирается корректный ответ: редирект на релевантную замену либо статус 404 или 410, если замены нет. Массовая выдача ошибок по индексируемым адресам ухудшает оценку сайта, но и редирект «куда-нибудь» не решение.
- Кириллические и устаревшие адреса. Часть старых URL содержит кодировки и форматы, которые новая система не порождает. Они обрабатываются картой соответствия как исключения, а не подгоняются правилом.
- Дубликаты клиентов при переносе. Один человек мог оформлять заказы несколько раз с разными адресами почты. Правило объединения определяется до миграции; при неоднозначности записи сохраняются раздельно, а не сливаются наугад.
- Расхождение остатков в первые часы. Наблюдение за обменом ведётся в усиленном режиме, пока не пройдёт полный цикл синхронизации.
Безопасность и работа с данными
Копия боевых данных в тестовой среде обезличивается: контактные данные клиентов заменяются, доступ ограничен. Персональные данные не покидают контур без необходимости.
Пароли пользователей не переносятся в открытом виде и не восстанавливаются. Если формат хеширования на новой платформе отличается, применяется прозрачная перехеширация при первом успешном входе — иначе всем клиентам придётся восстанавливать доступ, что даёт всплеск нагрузки на поддержку в худший момент.