Як закешований React-бандл відправляв дані в неправильну базу даних

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

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

Ми помилялися.

Інженер перевірив логи на старому API-сервері. Цей сервер мав бути вимкненим. Але це було не так. Він отримував реальні запити клієнтів і записував дані в стару базу даних.

Протягом двох годин реальні дані клієнтів потрапляли не туди.

Ось чому це сталося і як ми це виправили.

Проблема

React-додатки на CDN, таких як AWS Amplify, замінюють змінні оточення під час збірки (build time). Коли ви запускаєте збірку, бандлер знаходить кожну змінну і замінює її жорстко закодованим рядком.

URL-адреса API була фізично вбудована в JavaScript-файл.

Коли ми зробили деплой, нові користувачі отримали новий бандл. Але існуючі користувачі, у яких додаток був відкритий, не оновлювали сторінку. Вони продовжували працювати зі старим бандлом, у якому була жорстко прописана стара URL-адреса.

Оскільки старий сервер усе ще працював, ці клієнти отримували статус 200 OK. Все виглядало добре. Помилка була «тихою». Тихі помилки — найнебезпечніший тип багів.

Трирівневе рішення

Ми створили три рівні захисту, щоб це ніколи не повторилося.

1. Конфігурація під час виконання (Runtime Configuration) Ми припинили «зашивати» URL-адреси в JavaScript-бандл. Замість цього ми використовуємо файл config.json у папці public. Бандлер не чіпає цей файл. Додаток завантажує цей файл під час виконання (runtime) перед рендерингом. Це гарантує, що нові сесії завжди отримуватимуть правильну URL-адресу.

2. Сповіщення через WebSocket Конфігурація під час виконання не допомагає користувачам із відкритими вкладками. Ми прив'язали наш процес деплою до WebSocket-сервера. Коли Amplify завершує збірку, він викликає webhook на нашому API. Потім сервер надсилає повідомлення всім підключеним клієнтам. Якщо користувач використовує стару версію, з'являється банер із проханням оновити сторінку.

3. Управління кешуванням Ми оновили налаштування CloudFront. Точки входу, такі як index.html та config.json, тепер мають параметр no-cache. Це гарантує, що користувачі завжди завантажують останні файли, а не застарілі версії з edge-вузла CDN.

Уроки

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

Розгортання — це не лише про завантаження коду. Це про те, щоб переконатися, що кожен клієнт зрештою використовує правильний код.

Джерело: https://dev.to/sugan_dev/how-a-cached-react-bundle-sent-production-data-to-the-wrong-database-55n9