Устранение простоя с помощью обновлений службы с версиями

Исторически администраторы должны были использовать сервер в автономном режиме для обновления и обновления локального программного обеспечения. Однако простой — это полный неstarter для глобальных служб 24×7. Многие современные облачные службы являются критически важной зависимостью для пользователей для запуска своих предприятий. Нет хорошего времени, чтобы начать работу системы, так как команда может обеспечить непрерывную службу при установке важных обновлений безопасности и компонентов?

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

Обновление слоев отдельно

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

Часто управление версиями проще обрабатывать в коде приложения. Более крупные системы обычно имеют довольно много устаревшего кода, например SQL, который находится в своих базах данных. Вместо дальнейшего усложнения этого SQL код приложения должен справиться с сложностью. В частности, можно создать набор классов фабрики, которые понимают управление версиями SQL.

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

Так как это на самом деле работает? Например, предположим, что ваша команда в настоящее время развертывает Sprint 123. Двоичные файлы понимают схему базы данных Sprint 123 и понимают схему Sprint 122. Общий шаблон — работать с обеими версиями и спринтами N и N-1 схемы SQL. Двоичные файлы запрашивают базу данных, определяют версию схемы, с которой они разговаривают, а затем загружают соответствующую привязку. Затем код приложения обрабатывает ситуацию, когда новая схема данных пока недоступна. После того как новая версия будет доступна, код приложения может начать использовать новые функции, включенные последней версией базы данных.

Перекат только с уровнем данных

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

Последовательность развертывания

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

Первое, что мы делаем, — это управление данными, возможно, в параллельных таблицах с помощью триггера SQL для поддержания синхронизации данных. Миграция больших данных и преобразования иногда должны выполняться несколькими шагами по нескольким развертываниям в нескольких спринтах.

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

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

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

Веб-интерфейс также должен обновляться без нарушения пользователей. При обновлении файлов JavaScript, таблиц стилей или изображений избегайте смешивания старых и новых версий, загруженных клиентом. Это может привести к ошибкам, которые могут потерять работу во время выполнения, например поле, редактируемое пользователем. Поэтому следует версии всех файлов JavaScript, CSS и изображений, помещая все файлы, связанные с развертыванием, в отдельную папку с версиями. Когда веб-интерфейс выполняет вызовы к уровню приложения, ресурсы с указанной версией загружаются. Только если действие пользователя приведет к полному обновлению страницы, новый веб-интерфейс загружается в браузер. Взаимодействие пользователя не нарушается обновлением.

Следующие шаги

Корпорация Майкрософт является одной из крупнейших в мире компаний по разработке программного обеспечения на протяжении десятилетий. Узнайте, как корпорация Майкрософт работает с надежными системами с devOps.