Pull to refresh

Comments 14

Все очень хорошо пока не меняется база данных так что добавляется, допустим, поле NOT NULL и старая версия не перестает работать на вставку данных. К сожалению в таком случае надо будет делать 2 последовательных релиза первый из которых добавит поле, а второй добавит условие NOT NULL

Если исключить вариант, что забыли про конфликт, то релиз катится в три (или больше) шага.
1) промежуточная версия — чтобы писать not null в бд
2) заполняем в бд старые данные с null
3) катим релиз с not null

Подразумевается, что с обновлением базы проблем никогда возникнуть не может?

Да. Именно в этом посыл. Обновление БД разрабатывается так, чтобы не было проблем не только с новой версией ПО, но и с предыдущей.

Обычно все как раз забывают про конфликт и все падает.

Хорошая практика в этом случае — тестирование. Накатываем миграции новой версии и тестируем старую версию так же, как и при её релизе, только вот уже на новой структуре БД (возможен сокращенный вариант тестирования, но тогда растут риски).

Спасибо за статью. Кейс с переименованием и правда очень сложный. После прочтения у меня возникли некоторые вопросы

  1. Сколько времени вы ждёте прежде чем переключаться между версиями?

  2. Как вы понимаете, что все зависимые сервиса перешли на новую версию? Что делаете с теми потребителями о которых вы не знаете или не имеете контактов в с ними, как они узнают, что скоро будет удалено устаревшее поле LastName?

  3. Кто отслеживает, что разработчик не забыл удалить не используемое поле?

Практичные вопросы. Разберу их по порядку.


Сколько времени вы ждёте прежде чем переключаться между версиями?

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


Как вы понимаете, что все зависимые сервиса перешли на новую версию?

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


Что делаете с теми потребителями о которых вы не знаете или не имеете контактов в с ними, как они узнают, что скоро будет удалено устаревшее поле LastName?

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


Кто отслеживает, что разработчик не забыл удалить не используемое поле?

Для отслеживания есть несколько механизмов:


  • пометки TODO: в коде;
  • атрибут [Obsolete];
  • создание задачи на удаление в бэклоге;
  • формирование диаграммы БД в CI — DocOps. Такой подход позволяет видеть структуру базы данных не только разработчикам, но и остальным членам команды, в том числе QA, аналитикам… Чем больше глаз, тем больше шансов, что ничто не будет забыто.
    Кстати о DocOps. Я планирую освятить эту тему в будущем.

Ещё бывает нужно заменить базу данных полностью. Например, поменять ей версию (MySQL 5.7 -> MySQL 8). Там также бывает blue-green deployment, причем уже не такой тривиальный. Через одновременную работу 2х баз данных с синхронизацией через binary log.

Весьма сложный кейс, но и такое бывает. Здесь технику blue-green deployment разумно будет сочетать с использованием feature toggles для возможности переключения строки соединения "на лету".

Возможно, вы выбрали неудачный пример — но зачем в примере все так сложно?
Ведь никакой технической необходимости создавать и заново заполнять поле данных с новым именем из-за изменения имени свойства в модели нет: для разрешения этого вроде как достаточно прописать ColumnAttribute со старым именем поля для переименованного свойства.
Или вы просто не захотели приводить более сложный, но более похожий на реальный пример?

Сложный пример переименования выбран не случайно — он состоит из составляющих, которые демонстрируют в том числе подходы добавления (как уже было подмечено в комментарии выше), а так же удаления.

Если честно. непонятно почему вы модель базы данных выкладываете в API. Я не верю что у вас нет навигационных свойств которые не должны попадать в API.

По нормальному надо делать DTO, в вашем случае PersonDTO

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

Sign up to leave a comment.