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

Принципы микросервисов

Роль, которую могут играть принципы, мы рассматривали в главе 2. Принципы складываются из утверждений о том, как все должно делаться, и из разъяснения причин, по которым все должно делаться именно таким образом. Они помогают нам выстроить различные решения, которые приходится принимать при создании наших систем. Конечно же, вы должны определить собственные принципы, но я считаю, что есть смысл изложить мое видение того, как выглядят ключевые принципы микросервисных архитектур, обобщенный вид которых представлен на рис. 12.1. Эти принципы призваны помочь нам в создании небольших автономных сервисов, успешно выполняющих совместную работу. Все они по крайней мере единожды уже были рассмотрены в этой книге, поэтому ничего нового вы здесь не найдете, но ценность рисунка определяется тем, что в нем передана только суть.

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

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

Рис. 12.1. Принципы микросервисов

Модель, построенная вокруг бизнес-концепций

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

Внедрение культуры автоматизации

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

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

Сокрытие подробности внутренней реализации

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

При любой возможности отдавайте предпочтение применению технологически нейтральных API-интерфейсов, чтобы получить свободу использования различных технологических стеков. Подумайте о применении технологии передачи репрезентативного состояния REST, оформляющей разделение подробностей внутренней и внешней реализации which. Те же самые идеи можно принять за основу и при использовании удаленных вызовов процедур (RPC).

Всесторонняя децентрализация

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

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

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

Независимое развертывание

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

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

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

Изолирование сбоев

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

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

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

Всестороннее наблюдение

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

А когда не следует применять микросервисы?

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

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

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

Напутствие

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

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