Как закэшированный React-бандл отправлял данные не в ту базу данных

Мы работали в условиях жесткого дедлайна. Команда бэкенда перешла на новый API и новую базу данных. Команда фронтенда обновила переменные окружения в AWS Amplify и запушила код.

Деплой прошел успешно. Мы закрыли ноутбуки. Мы думали, что всё готово.

Мы ошибались.

Один инженер проверил логи на старом API-сервере. Этот сервер должен был быть отключен. Но нет. Он принимал реальные запросы клиентов и записывал данные в старую базу данных.

В течение двух часов данные реальных клиентов уходили не туда.

Вот почему это произошло и как мы это исправили.

Проблема

React-приложения на CDN, таких как AWS Amplify, заменяют переменные окружения во время сборки. Когда вы запускаете сборку, бандлер находит каждую переменную и заменяет её жестко прописанной строкой.

URL API был физически встроен в JavaScript-файл.

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

Поскольку старый сервер всё еще работал, эти клиенты получали статус 200 OK. Всё выглядело нормально. Сбой произошел незаметно. «Тихие» ошибки — самые опасные.

Трехуровневое решение

Мы выстроили три уровня защиты, чтобы это больше никогда не повторилось.

1. Конфигурация во время выполнения (Runtime Configuration) Мы перестали вшивать URL в JavaScript-бандл. Вместо этого мы используем файл config.json в папке public. Бандлер не трогает этот файл. Приложение загружает этот файл во время выполнения перед рендерингом. Это гарантирует, что новые сессии всегда будут получать правильный URL.

2. WebSocket-уведомления Конфигурация во время выполнения не помогает пользователям с открытой вкладкой. Мы привязали процесс деплоя к нашему WebSocket-серверу. Когда Amplify завершает сборку, он вызывает вебхук на нашем API. Затем сервер отправляет сообщение всем подключенным клиентам. Если пользователь использует старую версию, появляется баннер с предложением обновить страницу.

3. Управление кэшем Мы обновили настройки CloudFront. Для точек входа, таких как index.html и config.json, теперь установлено значение no-cache. Это гарантирует, что пользователи всегда будут загружать последние файлы, а не устаревшие версии с узла CDN (edge node).

Уроки

• Конфигурация на этапе сборки — это ловушка для значений, которые меняются между развертываниями. • Молчание опаснее шума. Заставляйте старые системы выдавать явные ошибки, используя статус 410 Gone. • Сжатые сроки приводят к ошибкам в ручных операциях. Автоматизируйте процесс вывода систем из эксплуатации. • Мониторьте то, что вы отключаете, а не только то, что вы включаете.

Развертывание — это не просто отправка кода. Это процесс обеспечения того, чтобы каждый клиент в итоге работал с правильной версией кода.

Источник: https://dev.to/sugan_dev/how-a-cached-react-bundle-sent-production-data-to-the-wrong-database-55n9