Нулевое время простоя / сине-зеленое развертывание одностраничного приложения (SPA)

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

Обсуждая это, мы выявили один крайний случай. После того, как пользователь загрузит страницу в своем браузере, ее нельзя удалить из памяти, пока он не перезагрузит страницу. Это означает, что если пользователь загружает страницу и начинает работать с веб-сайтом (например, начинает печатать длинную статью, как это делаю я сейчас), то он не может получить ее обновленную версию, пока не перезагрузит страницу.

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

  1. В случае, если мы внесем критическое изменение в HTTP Api, который используется для обслуживания спа, пользователь не сможет сохранить свою статью (потеря данных!) Или может получить другую ошибку при выполнении другого действия, связанного с серверной частью.
  2. Когда пользователь переходит на новую страницу без перезагрузки SPA, он может получить шаблон следующей страницы или некоторого элемента управления, несовместимого с внешним старым контейнером. Это может привести к нарушению разметки или логики приложения.
  3. Мы не можем заставить пользователя повторно войти в систему, так как он может печатать свою статью, и это просто плохой UX.

Принимая во внимание все эти моменты, можно предложить следующее решение:

  1. Пользователь 1 загружает v1 SPA в свой браузер.
  2. Наряду с токеном аутентификации в браузер отправляется информация о версии (например, с помощью JWT).
  3. Мы хотим развернуть v2 версию нашего приложения. Мы раскручиваем версию v2, но не отключаем v1.
  4. Пользователь 2 загружает версию 2 SPA в свой браузер.
  5. Пользователь 1 переходит на следующую страницу в SPA. Балансировщик нагрузки проверяет информацию о версии в своем токене и направляет трафик пользователя 1 на сервер v1.
  6. Пользователь 2 таким же образом перенаправляется на v2.
  7. Пользователь 1 выходит из приложения и закрывает браузер.
  8. Пользователь 1 снова входит в систему - на этот раз он получает v2.
  9. После того, как приложение v1 долгое время не получает трафика, оно утилизируется.

Однако при таком подходе возможно иметь несколько версий, более двух (например, если пользователь остается в сети целый день или два). Это означает, что мы не сможем перенести базу данных на новую схему, пока последний пользователь не выйдет из системы (представьте, как это может работать для таких сайтов, как Facebook). Наличие нескольких версий не проблема, однако такие инструменты, как Docker и Rancher, позволяют нам это легко сделать.

Также на шаге 7. Пользователь должен перезагрузить страницу или закрыть браузер, иначе он все равно будет работать с v1, и мы не сможем заставить его перейти к следующей версии.

У меня вопрос: какой подход вы используете, чтобы добиться нулевого времени простоя / сине-зеленого развертывания одностраничных приложений?

Как вы управляете временем жизни «синей» версии вашего приложения при переключении трафика на «зеленую» версию, особенно в отношении существующих «синих» клиентских приложений.

Вы решили эти проблемы, знаете ли вы какое-нибудь другое решение?


person gerichhome    schedule 05.10.2016    source источник
comment
Мне интересно узнать, что вы в итоге решили. Я сейчас обдумываю такую ​​проблему. Спасибо.   -  person Martin    schedule 17.03.2018
comment
На самом деле у меня не было точного решения - я проводил своего рода исследование или POC сине-зеленого подхода к развертыванию. Одно из возможных решений - включить абсолютное истечение срока действия сеанса и заставить каждого пользователя выходить из системы не реже одного раза в день. В этом случае вам также необходимо заставить пользователя перезагрузить страницу браузера и перезагрузить приложение JS. В этом случае переключение может произойти после завершения самого старого сеанса входа в систему.   -  person gerichhome    schedule 29.03.2018


Ответы (4)


Я довольно долго боролся с этой проблемой и пробовал несколько подходов, и один из них работал очень хорошо:

  • Используйте хешированные имена при объединении SPA (включая изображения и др.)
  • Используйте сегмент статических ресурсов (например, AWS S3) и загрузите в него все ресурсы до начала процесса развертывания.
  • Обеспечьте соблюдение внутренних правил, чтобы свести к минимуму нарушение контрактов API (например, поля из конечной точки должны удаляться только после выпуска X)
  • Развертывание по обычной сине-зеленой стратегии

Обоснование

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

person Erick Wilder    schedule 09.05.2018

Один из подходов, который вы можете рассмотреть, - это постепенная перезагрузка SPA в такой момент, когда это не является обременительным (или даже незаметным) для конечного пользователя.

Предлагаемый подход:

Цветные версии системы (компоненты, предоставляющие серверные службы, API и интерфейс) знают (время выполнения предоставляется) свой цвет. Компонент, предоставляющий пользователям интерфейсное приложение, встраивает эту цветовую информацию в SPA. Затем он отправляется (через cookie или настраиваемый HTTP-заголовок) с каждым запросом SPA к бэкэнду.

Компонент, который маршрутизирует вызовы API (шлюз API, балансировщик нагрузки, nginx, HAproxy, настраиваемый маршрутизатор на базе Zuul и т. Д.), Знает об этой цветовой информации и использует ее для направления трафика в инфраструктуру соответствующего цвета.

Кроме того, существует общедоступный URL-адрес (не предоставляемый цветной инфраструктурой - например, файл S3, предоставляемый через CloudFront или другой прокси) с цветом последней версии. SPA проверяет эту версию каждый заданный период времени (60 или 120 секунд). Если версия не совпадает с той, которая была предоставлена ​​при загрузке SPA, тогда на главной следующей странице изменения маршрута перезагружается физически, вместо того, чтобы реализовывать эту навигацию только в браузере.

Вы можете выбрать, какие изменения маршрута проверяют эту версию таким образом, чтобы это было наименее навязчивым для пользователя (возможно, почти незаметным).

Если вы выберете несколько маршрутов, которые используются каждый день всеми пользователями, то довольно скоро все пользователи перейдут на последний цвет. С теми, кто долгое время не использовал открытое окно браузера (компьютер находился в спящем режиме на две недели?), Можно принудительно перезагрузить компьютер после определенного периода бездействия.

Надеюсь, мне удалось наконец-то заставить себя звучать немного связно :-)

С уважением, Войтек

person wciesiel    schedule 07.09.2018
comment
Отличный ответ! Я также думаю (поскольку я узнал о некоторых новых для меня концепциях PWA), что приложение может быть построено с архитектурой App Shell, и оно может позволить вам перезагружать все в таком виде навигации, но не перезагружать оболочку (она может будет хорошо) - person gerichhome; 10.09.2018
comment
Интересная идея скрыть перезагрузку за маршрутизацией! - person Yuri; 04.01.2021

Не уверен, зачем вам проводить полный пересмотр своего пользовательского интерфейса, поскольку это всегда требует обучения. Практически в реальном мире было бы плохой идеей немедленно переключаться на новый пользовательский интерфейс. Вы могли бы позволить клиентам переключаться на новый интерфейс в течение определенного периода времени, а затем отключить старую версию после предупреждения. Не стоит тратить силы на такой переключатель реального времени. A / B-тестирование может быть способом познакомить клиентов с новым интерфейсом, а затем провести фактическое развертывание.

person Rohitdev    schedule 26.01.2018

Техника, которую вы описываете, называется сине-зеленым развертыванием; Вы начинаете с существующего сервера (синий) и добавляете обновленный сервер (зеленый). Весь новый трафик с этого момента перенаправляется в зеленую среду. Синяя среда предназначена только для обслуживания существующих HTTP-соединений, а также для дополнительного «отката» в случае, если в зеленой среде возникнут серьезные проблемы. В конце концов, «синюю» среду можно удалить, когда она завершит обслуживание всех своих запросов.

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

person Bernard    schedule 05.10.2016
comment
Да, я знаю, что это сине-зеленое развертывание, но вопрос, точнее, о том, как это работает с одностраничными приложениями, когда вы не можете заставить пользователя обновить его клиентское приложение, когда вы обновляете свою серверную часть. - person gerichhome; 05.10.2016