Неправильная точка зрения может свести на нет усилия по созданию микросервисов с самого начала.

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

Или мы так считаем.

Но если именно так мы рассматриваем проект — как одно огромное усилие с началом, кучей боли и, наконец, концом, — тогда нам суждено потерпеть неудачу.

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

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

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

Наша команда по продукту, конечно, постарается проявить понимание. Но в конце концов их терпение истощится. Продажи будут задаваться вопросом, когда у них появятся новые функции для продажи. И вскоре наши руководители высшего звена — когда-то восторженные сторонники проекта — начнут сомневаться в его ценности.

Мы напомним им всем, что усилия окупятся (когда-нибудь!) и что пока нам просто нужно продолжать. Но молча мы, инженеры, будем задавать себе один и тот же вопрос: «Действительно ли это того стоит?»

Другими словами…

Все в компании, включая вас, потеряют интерес

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

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

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

Как нам подойти к проекту?

Смотреть на наш переход к микросервисам как на один монолитный проект явно неправильно. Как же тогда должны на это смотреть? Учти это:

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

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

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

  • Наш проект должен быть разделен на отдельные части, каждая из которых приводит к заранее определенному результату.
  • После завершения каждый результат должен быть развернут в рабочей среде.
  • Каждый результат должен оставлять нас в лучшем, а не в худшем положении.
  • По возможности эти результаты должны соответствовать потребностям бизнеса.

Дискретные части

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

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

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

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

  • просматривать и выбирать продукты из монолита (как они могли до сих пор) и
  • совершить покупку с помощью наших недавно созданных микросервисов.

В качестве альтернативы мы можем решить создать новые элементы инфраструктуры, которые потребуются нашим микросервисам. Например, мы можем создать кластер Kubernetes, на котором будут развернуты наши сервисы. Или, если нам нужна шина событий (подсказка: скорее всего, понадобится), то мы можем создать кластер Kafka. Каждый из этих подпроектов будет иметь свое собственное определение готовности: образ, развернутый в качестве контейнера для нашего кластера k8s, или сообщение, опубликованное и получающее в/из нашей шины событий, соответственно.

Дело в том, что эти усилия должны быть четко определены и автономны. И у каждого должна быть достижимая точка, в которой мы можем объявить их выполненными.

Прямо к производству

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

Это не должно быть новой идеей. Большинство из нас стараются развернуть готовую, протестированную работу как можно быстрее. Но при создании наших первых микросервисов мы не всегда следуем этой мантре. Возможно, это отражает менталитет, что это предложение по принципу «все или ничего» — что мы должны развертывать либо монолит, либо микросервисы, но не то и другое одновременно. Возможно, это коренится в очень понятном страхе перед тем, что произойдет, когда мы начнем получать трафик через наши новые сервисы.

Именно по этим причинам мы должны развертывать наши новые функции на основе микросервисов после их создания.

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

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

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

Суть этой статьи в том, что мы не должны рассматривать наш проект микросервисов как единый монолитный проект. Он не завершен ни на 0%, ни на 100%. То же самое касается нашей стратегии развертывания. Нам не нужно запускать ни 100% монолит, ни 100% микросервисы. Мы можем — и должны — чувствовать себя комфортно, когда работаем над проектом.

Оставив нас в лучшем положении

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

Ранее мы видели пример взятия определенной функции — в данном случае нашей функции оформления заказа — и создания ее заново с нашей новой архитектурой. Что если вместо этого мы решим вытащить целую функцию (например, уровень доступа к данным) из нашего монолита и перенести ее в микросервисы? Другими словами, что, если вместо того, чтобы перемещать вертикальный объект из нашего монолита, мы вместо этого вытягиваем горизонтальный слой?

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

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

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

Давайте сравним с выделением вертикальной функции; например корзина. Эта работа, конечно, все еще будет сложной. Но поскольку команда, работающая с корзиной, работает над достижением четко определенной цели, вероятность ее достижения высока. И когда они делают? После того, как они продемонстрируют свои новые службы, работающие в производственной среде, когда они будут работать автономно, когда они будут развертываться по собственному графику? Реакция людей будет не «зачем мы это делаем?» но вместо этого: «теперь я понимаю, почему мы это делаем!»

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

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

Так в чем же разница между ними?

Что ж, инфраструктура управления сеансами и аутентификацией, которую мы построили бы для поддержки сервисов корзины покупок? Это было бы инвестицией. Эта же инфраструктура будет поддерживать следующую вертикаль, которую мы вытянем, и все последующие.

Но те прокладки, которые мы установили, чтобы позволить монолиту вызывать микросервисы данных? В конечном итоге это будет одноразовая работа. Это если нам повезет. Если вместо этого наш проект микросервисов рухнет в этот момент, то мы застрянем с прокладками на неопределенный срок.

Это приводит к самому большому выводу из этого раздела: приступая к части нашего проекта микросервисов, мы должны всегда спрашивать себя: «Если бы это была последняя часть, которую мы когда-либо могли сделать, оставим ли мы себя в лучшем или хуже положении?»

Согласование с потребностями продукта

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

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

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

Заключительная часть

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

Мы можем посмотреть на это так: поскольку мы заменяем части нашего монолита микросервисами, мы неизбежно причиняем боль… как себе в разработке, так и другим во всей организации. Эта боль, в свою очередь, приведет к падению энтузиазма по поводу нашего проекта. Чтобы противостоять этой боли и этому падению энтузиазма, нам нужны победы на этом пути.

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

Вторая диаграмма показывает, как можно сохранить энтузиазм и поддержку проекта, если рассматривать проект в целом как серию подпроектов.

Поэтому вместо одного длительного путешествия по темному и страшному месту мы хотим рассматривать наш проект микросервисов как серию шагов. Каждый из этих шагов сам по себе представляет собой небольшое краткое путешествие. И каждый должен вести нас в том направлении, в котором мы хотим двигаться.

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

Находите эту историю полезной? Хотите узнать больше? Просто подпишитесь здесь, чтобы получать мои последние новости прямо на ваш почтовый ящик.

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

Запланируйте сеанс DDIChat в разделе Управление и корпоративный консалтинг:



Подать заявку на участие в программе DDIChat Expert можно здесь.