Просто о микросервисах
Чуть ли не каждый второй, кто впервые сталкивается с MSA (Micro Service Architecture), на первых порах восклицает: «Да я эти микросервисы еще …надцать лет назад». Отчасти они правы. И я тоже был из этой самой половины, и не понимал — почему такой шум?
В самом деле! Ведь MSA — это тоже про разработку софта. Какие здесь могут быть революции? Все методики знакомы. В некоторых местах можно даже удивиться: «А разве бывает по-другому»? Фанаты Agile и DevOps тоже скажут, что это всё наше, родное.
Но всё же прошу вас набраться терпения и продолжить читать дальше.
Что такое микросервисная архитектура (MSA)
Если перефразировать Википедию, то определение микросервисной архитектуре может быть таким:
MSA — принципиальная организация распределенной системы на основе микросервисов и их взаимодействия друг с другом и со средой по сети, а также принципов, направляющих проектирование архитектуры, её создание и эволюцию.
Что такое микросервис (MS)
С архитектурой разобрались быстро. С микросервисами давайте поподробнее.
Понять суть микросервиса проще всего на сравнении, или даже противопоставлении его крупному приложению — монолиту. В отличии от MSA, я не буду давать определение микросервису, а перечислю его наиболее важные характеристики.
А дальше мы рассмотрим каждую из них подробнее.
Я выделил восемь свойств микросервиса:
- Он небольшой.
- Он независимый.
- Он строится вокруг бизнес-потребности и использует ограниченный контекст (Bounded Context).
- Он взаимодействует с другими микросервисами по сети на основе паттерна Smart endpoints and dumb pipes.
- Его распределенная суть обязывает использовать подход Design for failure.
- Централизация ограничена сверху на минимуме.
- Процессы его разработки и поддержки требуют автоматизации.
- Его развитие итерационное.
Небольшой
Что такое «небольшой»? Такая малоинформативная формулировка! На самом деле, по-другому не скажешь. Каждый должен самостоятельно определиться с размером. Лучше всего на практике. В качестве индикативных оценок можно ориентироваться на рекомендации экспертов. Размер микровервиса должен быть таким, чтобы выполнялось одно из условий:
- Один сервис может развивать одна команда не более чем из дюжины человек.
- Команда из полудюжины человек может развивать полдюжины сервисов.
- Контекст (не только бизнеса, но и разработки) одного сервиса помещается в голове одного человека.
- Один сервис может быть полностью переписан одной командой за одну Agile-итерацию.
Независимый
Микросервисная архитектура — воплощение паттернов High Cohesion и Low Coupling. Всё, что противоречит этому, отвергается беспощадно. В противном случае команду ждут большие проблемы. Так что микросервис обязан быть независимым компонентом.
Здесь попрошу вас не начинать холивар о том, что же такое «компонент». Давайте в рамках этой статьи сойдемся на том, что
Компонент — это единица ПО, код которой может быть независимо заменен или обновлен.
Конечно любая мало-мальски серьезная программа пишется с разбиением на компоненты, которые, безусловно, основываются на тех же принципах. Но в монолите общая кодовая база открывает возможности для нарушения низкой связанности. И при слабой дисциплине рано или поздно код превращается в спагетти.
Под такую формулировку компонента подходят и сторонние библиотеки. Здесь сложнее с нарушением границ произвольными связями, но не на много.
В то же время методология разбиения на отдельные микросервисы вынуждает придерживаться жесткого их разделения, ведь они должны отвечать более жестким критериям независимости.
Так, каждый микросервис работает в своем процессе и поэтому должен явно обозначить свой API. Учитывая, что другие компоненты могут использовать только этот API, и к тому же он удаленный, минимизация связей становится жизненно важной.
Такое разделение дает явный выигрыш с точки зрения независимого развития разных компонентов. И с учетом этого различные языки вводят конструкции, позволяющие явное создание независимых компонентов (например, модули в Java 9), и это перестает быть прерогативой микросервисного подхода.
Не хочу, чтобы создалось впечатление, будто в микросервисной архитектуре запрещено использование библиотек. Их использование не приветствуется, поскольку так или иначе приводит к зависимостям между микросервисами, но всё же допускается. Как правило, это допущение распространяется на инфраструктурные функции вроде логирования, вызова удаленного API, обработки ошибок и тому подобного.
Независимость микросервисов позволяет организовать независимый жизненный цикл разработки, создавать отдельные сборки, тестировать и развертывать.
Поскольку размер микросервисов невелик, то очевидно, что в крупных системах их будет немало. Управлять ими вручную будет сложно. Поэтому команда обязана иметь приемлемый уровень автоматизации согласно Continuous integration и Continuous Delivery.
Где же микросервис (бизнес-потребность)
Итак, вы решили спроектировать новый микросервис.
Определение его границ — самый важный шаг. От этого будет зависеть вся дальнейшая жизнь микросервиса, и это серьёзно повлияет на жизнь команды, отвечающей за него.
Основной принцип определения зоны ответственности микросервиса — сформировать её вокруг некоторой бизнес-потребности. И чем она компактнее, чем формализованней её взаимоотношения с другими областями, тем проще создать новый микросервис. В общем, довольно стандартный посыл. На нем основывается создание любых других компонентов. Вопрос только в том, чтобы в дальнейшем выдержать эту зону ответственности, что мы и обсуждали в предыдущем параграфе.
Когда границы микросервиса заданы и он выделен в отдельную кодовую базу, защитить эти границы от постороннего влияния не составляет труда. Далее внутри микросервиса создают свой микромир, опираясь на паттерн «ограниченного контекста». В микросервисе для любого объекта, для любого действия может быть своя интерпретация, отличная от других контекстов.
Но что делать, если границы оказались неправильными? В этом случае изменение функциональности в новом микросервисе ведет к изменению функциональности в других микросервисах. В результате «поплывут» интерфейсы всех зависимых микросервисов, а за ними интеграционные тесты. И всё превращается в снежный ком. А если эти микросервисы ещё и принадлежат разным командам, то начинаются межкомандные встречи, согласования и тому подобное. Так что правильные границы микросервиса — это основа здоровой микросервисной архитектуры.
Чтобы минимизировать ошибки при определении границ, нужно вначале их продумать. Поэтому оправданным является подход Monolith First, когда вначале систему развивают в традиционной парадигме, а когда появляются устоявшиеся области, их выделяют в микросервисы. Но всё течет и меняется. И границы тоже могут меняться. Главное, чтобы выигрыш от разбиения превышал сложности пересмотра этих границ. Такой подход к постепенному формированию набора микросервисов похож на итерационное развитие, используемое в Agile, ещё его называют «эволюционным проектированием» (Evolutionary Design).
Есть ещё одно интересное следствие создания микросервисов, соответствующее закону Конвея (Conwey Law).
Если организация использует монолитное приложение, то оно нарушает соответствие структуре и коммуникациям внутри организации. А команды разработчиков строятся вокруг архитектурных слоев монолита: UI, серверная логика, база данных.
Микросервисная архитектура приводит IT и бизнес в гармонию, с точки зрения Конвея. Поскольку микросервисы формируются вокруг бизнес-потребностей конкретных бизнес-подразделений, то архитектура предприятия начинает повторять оргструктуру и каналы социальной и бизнес-коммуникации. А команды становятся кроссфункциональными и формируются вокруг этих бизнес-потребностей / бизнес-подразделений.
Поскольку разные микросервисы получаются независимыми не только логически, но и технологически, а создавать их могут разные команды, ничто не мешает для каждого случая подбирать подходящие языки программирования, фреймворки и даже операционные системы.
Интеграция. Smart endpoints and dumb pipes
Интеграция микросервисов обходится без ESB, как центрального промежуточного звена. Наверное, комьюнити уже натерпелось от неудачных вариантов реализации этого подхода. То, что были и удачные — не принимается в расчет. Впрочем, ESB ещё и противоречит таким критериям как децентрализация и независимость. Таким образом, сложность интеграции распределяется с центрального звена в виде ESB непосредственно на интегрируемые компоненты: «умные конечные точки».
Для интеграции, как правило, используются простые текстовые протоколы, основанные на HTTP, чтобы нивелировать возможную технологическую разность микросервисов. REST-подобные протоколы являются практически стандартом. Как исключение, могут использоваться бинарные протоколы типа Java RMI или .NET Remoting.
Здесь есть дилемма. Конечно бинарные протоколы гораздо эффективнее. Но, во-первых, появляются технологические ограничения. Во-вторых, на бинарных протоколах сложнее реализовывать шаблон Tolerant Reader, сохраняя эффективность. В-третьих, опять появляется зависимость провайдера и потребителей, поскольку они оперируют одними и теми же объектами и методами, то есть связаны по кодовой базе.
Другая отличительная черта взаимодействия микросервисов — синхронные вызовы не приветствуются. Рекомендуется использовать один синхронный вызов на один запрос пользователя, или вообще отказаться от синхронных вызовов.
И еще пара замечаний.
- Основной сложностью разбиения монолита на микросервисы является не определение их границ. Они уже должны сформироваться и устояться. Сложность заключается в том, что локальные вызовы становятся удаленными. А это влияет не только на организацию вызовов, но и на стиль взаимодействия, так как частые вызовы уже не подходят. Скорее всего, надо пересматривать сам API, делать его более крупным, а, как следствие, пересматривать логику работы компонентов.
- Поскольку асинхронное событийное взаимодействие — практически стандарт в микросервисной архитектуре, то надо разбираться в создании событийной архитектуры (Event Driven Architecture), а сами микросервисы должны соответствовать требованиям Reactive.
Design for failure для распределенной системы
Одно из наиболее критичных мест в микросервисной архитектуре — необходимость разрабатывать код для распределенной системы, составные элементы которой взаимодействуют через сеть.
А сеть ненадежна по своей природе. Сеть может просто отказать, может работать плохо, может вдруг перестать пропускать какой-то тип сообщений, потому что изменились настройки файрвола. Десятки причин и видов недоступности.
Поэтому микросервисы могут вдруг перестать отвечать, могут начать отвечать медленнее, чем обычно. И каждый удаленный вызов должен это учитывать. Должен правильно обрабатывать разные варианты отказа, уметь ждать, уметь возвращаться к нормальной работе при восстановлении контрагента.
Дополнительный уровень сложности привносит событийная архитектура. А отладку такой системы — не одного микросервиса, а системы, где много потоков разнонаправленных неупорядоченных событий — даже трудно представить. И даже если каждый из микросервисов будет безупречен с точки зрения бизнес-логики, этого мало. По аналогии со спортом, «звёзды» не гарантируют звездную команду, ведь в команде важнее не «звезды», а слаженность всех её игроков.
И поскольку сложность таких систем очень высока, то проблему решают так.
- Не доводят систему до состояния «без сучка без задоринки». Это очень дорого. Конечно, это не значит, что система валится от первого дуновения. Она просто отвечает необходимым нефункциональным требованиям. Но в ней могут присутствовать ошибки, незначительно влияющие на ее устойчивость и производительность.
- С другой стороны вкладываются в инфраструктуру, которая помогает быстрее устранять нештатные ситуации. Должно быть полное покрытие кода unit тестами, интеграционными и тестами производительности. Должен быть интеллектуальный мониторинг, который не только моментально показывает неработающие места, но и сигнализирует об ухудшении состояния системы с прогнозированием возможных сбоев. Должно быть продвинутое распределенное логирование, позволяющее оперативно проводить расследования. И часто по результатам исправляются скрытые ошибки.
Децентрализация данных
Еще один из важнейших элементов в парадигме микросервисов.
Каждому микросервису по своей базе данных!
Лозунг популиста на выборах.
На самом деле и в монолите можно побороться за изолированность компонентов, например, на уровне серверного кода. Если время от времени изоляция даёт течь, современные инструменты предлагают продвинутые инструменты рефакторинга. Пользуйтесь. Хотя, как правило, на это находится время, только когда дела уже совсем плохи.
Теперь опустимся ниже, на уровень базы данных. Почему-то здесь на изолированность обращают внимание гораздо реже. В результате через пару тройку лет активного развития в базе данных монолита образуется если не хаос, то энтропия продвинутого уровня. Чтобы её побороть, мало уже одной строчки в бэклоге. Необходимы месяцы кропотливого и долгого труда.
В микросервисной архитектуре это решается гильотиной. Общей базы данных просто нет.
Помимо изолированности есть и побочные плюсы. Например, легче реализовать Polyglot Persistence, когда база подбирается под конкретные цели. Ничто не мешает делать это и без микросервисов, и так часто делают. Но всё же в одном случае это закон, в другом — исключение.
У этой медали есть оборотная сторона. Много баз, много контекстов, как их все согласовать? Старая техника распределенных транзакций сложна и обладает низкой скоростью. Возможно это иногда можно пережить. А вот необходимость синхронного взаимодействия нескольких микросервисов не может устраивать, и это не побороть.
Проблема решается нетрадиционно для монолита: отказом от постоянной согласованности данных. Добро пожаловать в мир Eventual consistency. На первых порах это вызывает волну «справедливого» гнева. Но если разобраться, то нужна ли повсеместно немедленная согласованность данных по окончании транзакции? При детальном рассмотрении значительную часть случаев можно отбросить. Где возможно, заменяют одну распределённую транзакцию серией локальных с компенсационными механизмами. Где-то мирятся с временной несогласованностью. А возможные ошибки либо обрабатывают за счет более сложной архитектуры, либо благодаря данным мониторинга. Если ничего не получается, то в особо экстремальных случаях всё же используют распределенные транзакции. Но это, с моей точки зрения, нарушение принципов MSA.
Монолит против микросервисов
Микросервисный подход несет довольно много проблем. Их найти не трудно и каждый может поупражняться.
Например, организационные вопросы. Как удержать в согласованном по версиям состоянии сотню микросервисов, которые еще и постоянно и непредсказуемо редеплоятся. А доступ к средам у каждого инженера каждой команды? Какая команда напишет интеграционные тесты? И если кто-то согласится, то попробуй еще их напиши для такой запутанной конфигурации. А если возникает ошибка, то чья она? Только той команды, у которой сломалось? Как не узнать вечером в пятницу, что версия API N-го сервиса, которой вы пользуетесь, вдруг стала deprecated?
Да, это действительно проблемы. Но команды, которые практикуют Agile и DevOps, уже знают решение. Поэтому начинать путь к микросервисной архитектуре стоит с внедрения этих практик.
Кроме организационных есть и чисто архитектурные. Как перейти от монолита, где всё синхронно, согласованно и едино, к распределенной событийной архитектуры, основанной на множестве мелких элементов, в которой надо учитывать возможную неконсистентность данных? Одного этого достаточно, чтобы задуматься: а стоит ли игра свеч? На этом фоне, например, падение скорости обработки одного запроса кажется мелочью. Хотя бы работает!
Тогда зачем? Если у вас нет проблем с вашим «монолитом», то не надо их искать.
Но если проблемы есть, то посмотрите на плюсы MSA, и возможно она спасет вас.
Разбиение на независимые компоненты даёт безусловные и неоспоримые преимущества: легкое понимание контекста, гибкость развития, управления и масштабирования. Независимость и небольшой размер дают и неожиданные плюсы с точки зрения инфраструктуры. Вам теперь не нужна монструозная машина за 100500 долларов. Микросервисы можно устанавливать на обычные дешевые машинки. И окажется, что даже все вместе они будут стоить на порядок меньше, но работать эффективнее той самой супермашины, на которую у вас в организации, наверняка, молятся и сдувают с неё пылинки.
Здесь уместен другой лозунг от популиста. Хотя, как и предыдущий, он вполне серьезен.
Каждому микросервису по своему серверу!
Продолжим агитировать за микросервисы. Посмотрим на лидеров IT-индустрии: Amazon, Netflix, Google и другие показывают впечатляющие результаты. Их гибкость и скорость вывода новых продуктов поражают. Поэтому игра точно стоит свеч! Здесь уместно вспомнить, что в упомянутых организациях команд «уровня бог» не одна и не две. Им сложности микросервисной архитектуры вполне по зубам. И если предложить создать монолит, то они и его сделают так, что он будет сверкать путеводной звездой.
А, например, Amazon вполне себе работал на монолите, уже будучи гигантом и имея миллиардные обороты. Сайт газеты Guardian до сих пор, а возможно и навсегда, базируется на микросервисах вокруг монолита. Это говорит о том, что значительная часть задач успешно, а зачастую и легче, решается без привлечения микросервисов.
И всё же это не значит, что микросервисы не для вас. Не боги горшки обжигают. Но бросаться с головой в омут тоже не стоит. Для микросервисной архитектуры команда должна быть достаточно зрелой. Один из главных критериев: использует ли она Agile и DevOps? Команда должна быть грамотной. Это сложно формализовать, но всё же попробуйте трезво оценить возможности. Например, насколько команда продвинута в Reactive и Event-Driven Architecture? К тому же команда должна иметь подготовленную инфраструктуру для поддержки микросервисной системы.
Впрочем, достаточно. Просто попробуйте. Надеюсь, получится и понравится.
- микросервисная архитектура
- raiffeisenbank
- raiffeisen
- архитектура
- микросервисы
- Блог компании Райффайзен Банк
- Высокая производительность
- Анализ и проектирование систем
- Проектирование и рефакторинг
- Микросервисы
Микросервисная архитектура
Микросервисная архитектура (microservices architecture, MSA) — это способ построения приложений, которые состоят из независимых друг от друга небольших модулей. Такие приложения называют микросервисами (microservices / MS).
Архитектура микросервисов принципиально отличается от более традиционного подхода, когда программу рассматривают как монолит. Микросервисы похожи на домики из конструктора: все блоки снимаются, их можно пересобрать или заменить. Поэтому такой подход считается более отказоустойчивым, и крупные компании внедряют его, чтобы повысить функциональность и надежность своих систем.
Созданием микросервисов занимаются команды из разработчиков, системных архитекторов и других специалистов.
DevOps-инженер
Помогайте компаниям быстрее выпускать качественный продукт
Микросервис и монолит
В противовес микросервисам существует так называемая монолитная архитектура программы — когда все приложение рассматривается как единое целое. Программа-монолит может состоять из модулей, но они тесно связаны друг с другом и не могут существовать один без другого. Их нельзя просто убрать или заменить. Если изменить один модуль, изменятся и другие.
Такие программы могут спокойно существовать, пока они небольшие и не слишком мощные. На стадии расширения начинаются проблемы. У монолитных систем есть ряд недостатков, которые как раз призваны устранить микросервисы.
Приложение сложно масштабировать. Его части не способны работать друг без друга. Поэтому, чтобы усилить производительность какой-то одной функции, придется запускать еще один экземпляр полноценного приложения. А это больше мощностей и затрат на развертывание. А еще такой подход не позволяет масштабировать приложение по частям — только целиком.
Хуже отказоустойчивость. Если в одной части монолитной структуры произойдет сбой, это скажется на всей системе. Остальные компоненты тоже не смогут работать, программа «упадет» целиком. Как итог — система дольше простаивает, а специалистам сложнее искать ошибку. Зачастую это большие финансовые потери.
Сложнее обновлять. Монолитная архитектура довольно консервативна: чтобы что-то добавить или убрать, понадобится переделывать всю программу целиком. Это требует больше времени, затрат, труда разработчиков. Кроме того, использовать можно не все инструменты. Не получится просто так переделать legacy-код под новые стандарты или внедрить новый стек технологий: нужно выбирать инструменты, совместимые с изначальной архитектурой. А если проблема обновления стоит остро — переписывать весь код.
Эти сложности возникают не сразу, а только на определенном этапе развития. Поэтому коммерческие программы часто разрабатывают по такому принципу: сначала делают небольшое и дешевое монолитное приложение, а по мере развития переделывают в микросервисы.
DevOps-инженер — связующее звено между всеми этапами создания продукта. Станьте незаменимым специалистом
за 6 месяцев.
Для чего нужны микросервисы
Архитектура приложения при микросервисном подходе совсем другая. Программа состоит из множества мелких блоков, а их функциональность не зависит один от другого. Поэтому микросервисы нужны, чтобы:
- иметь возможность дорабатывать и изменять каждый блок по отдельности;
- упростить обновления и развитие продукта;
- повысить отказоустойчивость всей системы;
- более эффективно распределить мощности по частям системы;
- лучше разделить обязанности внутри команды: каждый может делать что-то свое и не беспокоиться, как это повлияет на весь остальной продукт.
К разработке микросервисов приходят, когда программа становится слишком объемной, чтобы ее можно было эффективно обслуживать как монолит. Чаще под новую архитектуру переделывают уже существующие приложения, но бывает и так, что программа с нуля строится как микросервисная.
Например, если разработкой занимается крупная компания, и сразу ясно, что нагрузка на программу будет большая, надежнее сразу создать микросервис.
Особенности микросервисов
Модули. Большая система строится из распределенных программных модулей. Каждый из них должен быть небольшим, независимым от других, выполнять какую-то одну узкую функцию. Для управления модулями обычно нужна автоматизация, а развиваются они в несколько итераций — маленькими шагами.
Сообщение. Модули независимы, но общаются друг с другом и обмениваются информацией. Это обычно делают по схеме, которую называют Smart endpoints and dumb pipes — умные конечные точки и глупые каналы. Так называется паттерн, когда обработкой входящих и исходящих сообщений занимаются сами отправители и получатели — то есть модули. А каналы просто передают информацию и больше ничего не делают. Обычно микросервисы «общаются» по сети с помощью простых API.
Команда. Микросервисная архитектура накладывает свои требования к команде разработки. Есть мнение, что для каждого модуля нужен свой разработчик, а отдельно стоит выделить DevOps-инженера и других «глобальных» специалистов. Другое мнение гласит, что команда должна быть такой, чтобы ее можно было накормить двумя коробками пиццы — это правило в свое время внедрил Amazon.
Языки. Модули слабо связаны между собой, поэтому разработчики не обязаны использовать для всех одни и те же инструменты. Разные микросервисы в рамках одной системы вполне могут быть написаны на разных языках программирования и фреймворках, пользоваться совершенно различными технологиями.
В реальном мире при создании микросервисов чаще всего пользуются JavaScript для веб-модулей, C++ и Go для нагруженных модулей, которые должны работать быстро, Java для энтерпрайза и Python для вычислений и аналитики.
Инструменты и среды. Можно использовать любые библиотеки и фреймворки, которых требует задача. Но есть инструменты, которые необходимы любому микросервисному продукту. Это ПО не для конкретных модулей, а для менеджмента всей системы и настройки среды выполнения:
- Docker для контейнеризации данных;
- Kubernetes для управления контейнерами;
- системы для CI/CD — непрерывной интеграции и развертывания;
- сервисы для мониторинга и записи логов о работе приложения;
- инструменты для Service Discovery — автоматического обнаружения сервисов.
Пример микросервисной архитектуры
Очевидный пример — супераппы, многофункциональные приложения, которые объединяют в себе несколько функций. Зачастую эти функции очень разные, и если создать такое приложение в монолите, работать с ним будет очень тяжело.
Скажем, «ЯндексGo» последние годы можно использовать не только для заказа такси, но и для пересылки вещей, просмотра маршрутов общественного транспорта или аренды самоката. Это суперапп, и сложно представить, чтобы такой набор сложных функций реализовали монолитно. А еще на микросервисную архитектуру давно перешли такие крупные проекты, как Twitter (X) или Amazon.
Неожиданный пример микросервисной архитектуры из живой природы — гигантский осьминог. В каждом щупальце осьминога свой мозг, поэтому его конечности двигаются независимо друг от друга. А сам осьминог благодаря этому способен на очень сложные движения.
Отличия микросервиса от SOA
Похожий подход к архитектуре приложений — это SOA, или сервисно-ориентированная архитектура. Некоторые даже считают, что микросервисы и SOA по сути одно и то же. Это не совсем так. Скорее, микросервис можно назвать частным случаем SOA и одним из способов ее реализовать.
- В SOA входит большое количество подходов к разработке. Например, архитектура CORBA, или общая архитектура опосредованных запросов к объектам. Эти подходы необязательно похожи на микросервисы.
- В среднем SOA-приложения имеют меньшую степень гранулярности, то есть разбиения на мелкие части. В микросервисном приложении может быть несколько десятков или даже сотен модулей, а в SOA — в среднем не больше десяти.
SOA можно рассматривать как промежуточный этап при переходе от монолита к микросервисам.
Кто разрабатывает микросервисы
Сама по себе архитектура довольно сложная, нужно поддерживать много маленьких процессов и управлять ими. Поэтому над микросервисами обычно трудится целая команда специалистов:
- системный архитектор или проектировщик занимается созданием архитектуры программы, выделяет ее важные функции и детали;
- команды разработчиков непосредственно создают логику сервисов, поддерживают их и обновляют;
- DevOps фактически занимается менеджментом сервисов, развертывает их, оркестрирует, настраивает ПО для контейнеризации и управления множеством маленьких модулей.
Отличительная особенность микросервисов тут — необходимость иметь в команде DevOps-инженера. Без него управлять всей этой системой из сервисов очень сложно.
Преимущества микросервисной архитектуры
Гибкое масштабирование. С микросервисами можно легко управлять масштабом и нагрузкой. Если нужно нарастить производительность конкретного модуля, можно выдать ему больше мощностей или запустить еще один экземпляр процесса. Это удобнее, чем монолит, где нельзя выдать больше ресурсов только одному компоненту — нужно давать их системе в целом.
Удобные обновления. Если нужно что-то обновить — можно изменить только несколько сервисов и не трогать остальные. Не понадобится переписывать все, ведь модули независимы. А еще ненужные модули можно просто убрать, и это не слишком повлияет на работу системы в целом. Разворачивать обновления тоже проще, ведь заново запускать приходится не весь продукт целиком, а только отдельный сервис.
Отказоустойчивость. Микросервисы независимы друг от друга. Поэтому если один или даже несколько модулей выйдут из строя, это не повлияет на работу остальных. Это не значит, что микросервисы защищены от ошибок: просто эти ошибки с меньшей вероятностью «уронят» всю систему.
Возможность выбирать технологии. С микросервисами продукт не «привязан» к конкретному языку программирования и стеку инструментов. Правда, обязательно нужны системы для управления модулями — но даже тут можно выбрать из нескольких вариантов.
Независимость данных. Данные каждого микросервиса хранятся отдельно от других, поэтому изменения в модели данных одного модуля не затрагивают остальные. Хотя работа с данными в микросервисной архитектуре имеет свои особенности, независимость опять же помогает разным частям системы быть автономнее.
Наглядный контроль качества. Если в монолитной команде выше вероятность подхода «все отвечают за всё», то с микросервисами задачи легче распределить между командами. Каждый делает что-то свое, его результаты можно наглядно оценить. Качество выполнения задач проще отследить, а еще структурированными командами легче управлять.
Недостатки микросервисной архитектуры
Сложное проектирование. Спроектировать микросервисную архитектуру и ничего не забыть — намного более сложная задача, чем сделать монолитное приложение. Трудности начинаются еще на этапе деления на модули: сколько их должно быть, насколько мелкими их делать и так далее.
Большое количество модулей. Это одновременно и плюс, и минус. О плюсах подхода мы уже рассказали выше, минус же в том, что за всем этим количеством нужно следить. Приходится мониторить большие массивы информации — даже если автоматизировать этот процесс, поддержка продукта становится намного дороже.
Потребность в DevOps. Этот пункт вытекает из предыдущего. Микросервисная архитектура накладывает ограничения на методологию и состав команды. Без методологии DevOps микросервисное приложение практически невозможно поддерживать — из-за необходимости мониторить и оркестрировать модули. В целом повышается операционная сложность, растут требования к специалистам.
Проблемы с целостностью данных. В микросервисных системах растет риск неконсистентности данных, то есть их несогласованности. Если данные не целостные, вырастает риск ошибки. Информация слабо связана между собой, поэтому в разных частях системы могут храниться противоречивые сведения — возникает путаница.
Снижение производительности. Еще одно следствие того, что модулей много. Информация проходит более долгий путь: сначала переходит от одного модуля к другому, потом к третьему и так далее. В итоге такая система будет работать медленнее. Есть способы повысить скорость — но они требуют высокого профессионализма разработчиков и не универсальны.
Дороговизна. Все вышеперечисленное довольно дорого и разрабатывать, и поддерживать. Нужны платные специализированные инструменты, которые помогут управлять модулями и мониторить их состояние. Нужны квалифицированные специалисты и довольно большие мощности. Так что микросервисы — это в первую очередь решение для крупных и сложных проектов.
Для каких приложений подходит микросервисная архитектура
Микросервисы упрощают развитие больших систем, но для маленьких часто оказываются избыточными: слишком дорогими или громоздкими. Поэтому решение подойдет не для каждого приложения. Существуют категории программ, для которых микросервисы подходят лучше других:
- cloud native — архитектура облачных приложений очень часто построена на микросервисах. Облако идеально подходит для системы из слабо связанных между собой маленьких частей;
- супераппы и многофункциональные программы — чем больше компонентов и модулей, тем выше потребность в MSA. Особенно если эти модули в идеале нужно реализовать с помощью разных технологий;
- приложения с объемным кодом — сложно переписывать его целиком ради каждого обновления;
- программы, компоненты которых нагружаются по-разному или нагрузка «плавает» в зависимости от внешних факторов. Например, онлайн-магазины с сезонным спросом;
- приложения, для которых критичны быстрые обновления и непрерывная доставка — например, связанные с меняющимися трендами;
- приложения с большими командами разработчиков — это не характеристика программы как таковой, но тоже аргумент в пользу микросервисов. Чем больше людей в команде, тем сложнее поддерживать монолит: каждому приходится держать в голове работу всех остальных.
DevOps-инженер
Станьте DevOps-инженером и помогайте командам фокусироваться на создании качественного продукта. Профессия отлично подойдет разработчикам, тестировщикам и сисадминам
Простым языком о микросервисной архитектуре для начинающих
Расскажем о плюсах и минусах микросервисов, а также выясним, кому подходит технология.
Что такое микросервисная архитектура
Микросервисная архитектура — распространенный подход к разработке программного обеспечения, когда приложение разбивается на небольшие автономные компоненты (микросервисы) с четко определенными интерфейсами. Именно эта архитектура характерна для cloud-native приложений, которые сейчас популярны благодаря преимуществам, что открывают для бизнеса облачные среды.
В сообществе разработчиков программного обеспечения есть скептики, которые не считают микросервисы чем-то новым и называют их всего лишь ребрендингом сервис-ориентированной архитектуры (SOA, service-oriented architecture), получившей распространение в конце двадцатого века. Однако микросервисы и SOA не одно и то же. К SOA относится множество других шаблонов, среди которых: CORBA, web-сервисы, очереди сообщений, ESB. Поэтому микросервисы стоит воспринимать как конкретный подход к SOA, но не единственный.
Микросервисы vs Монолит
Прежде чем начать рассказ о микросервисах, стоит вспомнить другой тип приложений, который им чаще всего противопоставляют, — монолиты. Это приложения, построенные как единое целое, где вся логика по обработке запросов помещается внутрь одного процесса. Разумеется, монолиты могут иметь модульную структуру — содержать отдельные классы, функции, namespace (в зависимости от выбранного языка программирования). Но связи между этими модулями настолько сильны, что изменение каждого из них неизбежно отражается на работе приложения в целом.
Представьте себе кирпичную стену. Она возводится из отдельных блоков. При строительстве кирпичи еще отделимы друг от друга, но со временем, когда цемент затвердевает, они становятся неразрывно связаны. Вы можете продолжить стену в одном из направлений, но для того, чтобы коренным образом изменить ранее построенное, скорее всего, придется применить кувалду.
Рассмотрим для примера типичный интернет-магазин. Монолитное приложение для него будет использовать наверняка знакомую вам трехуровневую архитектуру, включающую:
- пользовательский интерфейс;
- серверную часть, отвечающую за бизнес-логику приложения и доступ к данным;
- базу данных.
Мы видим, что бизнес-функции приложения очень разнообразны: работа с каталогом товаров и корзиной, обработка заказов, их оплата и отслеживание статуса, ведение пользователей и так далее. Но на уровне приложения все они объединены в один монолитный блок. При разворачивании код для различных функций находится на одном сервере. Чтобы масштабировать приложение, вам необходимо запустить несколько его экземпляров на различных физических серверах.
Недостатки такой схемы монолитной архитектуры очевидны:
Избыточность сборок и развертывания
Даже небольшое изменение для одной из бизнес-функций будет приводить к необходимости сборки и развертывания новой версии всего приложения.
Невозможность масштабирования части приложения
Масштабировать приходится все приложение целиком, даже если это необходимо отдельно взятому компоненту с наименьшей производительностью. В нашем примере можно предположить, что обращения к каталогу товаров будут происходить значительно чаще оформления заказов — то есть именно для этой функции стоило бы выделить дополнительные ресурсы, но в монолите это невозможно.
Увеличение цены сбоя
Отказ одного модуля чаще всего сказывается на всей работе в целом в силу тесных связей внутри приложения.
Сложность внедрения новых технологий
Разработчик ограничен выбранным для приложения технологическим стеком. Хотя для ряда компонентов, возможно, было бы эффективно использовать иные технологии.
Организационные сложности
Требуется большая команда, которой тяжело управлять. При этом структура команды, вероятнее всего, будет соответствовать выбранной архитектуре: отдельные специалисты по пользовательскому интерфейсу, бизнес-логике и базе данных. И каждой из этих групп потребуется владеть экспертизой по всем бизнес-функциям, что со временем будет становиться все труднее.
Редкость обновлений
Так как изменения затрагивают все приложение, увеличивается время на их отладку и проверку, что приводит к редким выходам обновлений и увеличению числа выпускаемых изменений в одном релизе, а это, в свою очередь, повышает риски.
Сильная зависимость от модели данных
Любое изменение в базе данных будет сказываться на всем приложении и требовать значительных изменений кода.
Для небольших и редко обновляемых приложений такая архитектура может работать прекрасно. Но по мере наращивания функциональности межмодульные связи в монолите будут неизбежно увеличиваться и усложняться, изменения в одних модулях будут все больше влиять на другие — в итоге дальнейшее развитие таких систем становится крайне затруднительным. И вот тут самое время присмотреться к микросервисам.
В отличие от монолитов, в микросервисной архитектуре приложение строится как набор небольших и слабосвязанных компонентов (микросервисов), которые можно разрабатывать, развертывать и поддерживать независимо друг от друга.
Если монолитное приложение проще всего сравнить с кирпичной кладкой, то микросервисы похожи на всем знакомый конструктор Lego. У вас есть множество деталей с четкими стандартными границами для соединения друг с другом. Вы всегда можете пересобрать получившееся изделие, заменив или убрав какие-то из элементов без ущерба для остальных.
Каждый из сервисов отвечает за конкретную бизнес-задачу, имеет собственное хранилище данных и общается с другими сервисами через простые API-интерфейсы для решения более сложных задач. Так, в нашем примере можно выделить микросервисы по ведению каталога товаров, работе с корзиной, оформлению заказов, оплате и так далее.
Ключевые преимущества микросервисов по сравнению с монолитами
Простота развертывания
Можно развертывать только изменяющиеся микросервисы, независимо от остальной системы, что позволяет производить обновления чаще и быстрее.
Оптимальность масштабирования
Можно расширять только те сервисы, которые в этом нуждаются, то есть сервисы с наименьшей производительностью, оставляя работать остальные части системы на менее мощном оборудовании.
Устойчивость к сбоям
Отказ одного сервиса не приводит к остановке системы в целом. Когда же ошибка исправлена, необходимое изменение можно развернуть только для соответствующего сервиса — вместо повторного развертывания всего приложения. Правда, для этого еще на этапе проектирования микросервисов потребуется тщательно продумать связи между ними для достижения максимальной независимости друг от друга, а также заложить возможность корректного оповещения пользователя о временной недоступности определенного сервиса без ущерба для всей системы.
Возможность выбора технологий
Можно подбирать различные наборы технологий, оптимальные для решения задач, стоящих перед отдельными сервисами.
Небольшие команды разработки
При разработке микросервисов команды принято закреплять за конкретными бизнес-задачами (и сервисами, соответственно). Такие команды, как правило, показывают большую эффективность, а управлять ими легче.
Уменьшение дублирования функциональностей
Присутствует возможность повторного использования функциональности для различных целей и различными способами.
Упрощение замены сервисов при необходимости
Небольшие сервисы проще заменить на более подходящую версию или удалить вовсе — это несет значительно меньше рисков по сравнению с монолитным приложением.
Независимость моделей данных
Каждый микросервис, как правило, использует собственное хранилище данных — поэтому изменение модели данных в одном сервисе не влияет на работу остальных.
Используйте облачную платформу VK для развертывания микросервисных приложений
- Нет аккаунта? Регистрация
- Есть аккаунт? Войти
Готовые PaaS для быстрого старта: Kubernetes, облачные базы данных, Big Data
- Миграция в облако без даунтайма
- SLA 99,95% с финансовыми гарантиями
Недостатки микросервисной архитектуры: как с ними справиться
Несмотря на множество преимуществ, микросервисы далеко не всегда оказываются оптимальным вариантом, у них есть несколько особенностей, которые стоит учитывать при выборе архитектуры.
Распределенная система
Микросервисы по своей природе распределены, а это, как известно, имеет свои недостатки: удаленные вызовы медленнее и чаще подвержены сбоям. Если ваш микросервис обращается к десятку других микросервисов, а те, в свою очередь, вызывают еще несколько, то итоговое время отклика значительно возрастает. Также по мере увеличения взаимодействий микросервисов друг с другом возрастает и число возможных точек отказа.
Известны несколько путей решения этой проблемы:
- Первый — изменить детализацию своих вызовов таким образом, чтобы сократить их количество.
- Второй — использовать асинхронность: при параллельном выполнении нескольких вызовов конечное время отклика будет определяться самым медленным из них, а не суммой всех задержек.
Оба метода усложняют модель программирования и увеличивают требования к квалификации.
Усложнение процессов и повышение требований к команде
Рост числа небольших независимых сервисов неизбежно увеличивает операционную сложность. Возрастает роль непрерывной интеграции и доставки, ведь невозможно обрабатывать десятки услуг без автоматизации их тестирования и развертывания. Повышаются требования к мониторингу, особенно в силу технологической разнородности сервисов.
Чтобы справиться с возросшей нагрузкой, компании нужно овладеть целым рядом новых навыков и инструментов, и важнейший из них — внедрение культуры DevOps. Необходимо обеспечить тесное сотрудничество программистов, тестировщиков, инженеров сопровождения и прочих участников разработки продукта на всех этапах его жизненного цикла. Далеко не все организации смогут справиться с таким количеством изменений. Но культурные изменения необходимы.
Если разработка монолитных приложений без повышения квалификации и овладения новыми навыками со временем становится затруднительной, но разработка микросервисов — вовсе невозможна.
Необходимость поддержания согласованности приложения
Микросервисы порождают возможные проблемы с согласованностью из-за применяемого в них децентрализованного управления данными. В монолитном приложении можно выполнить множество связанных изменений за одну транзакцию, и вы будете уверены, что в случае сбоя произойдет откат и согласованность данных сохранится.
Микросервисам же требуется несколько ресурсов для выполнения цепочки изменений, распределенные транзакции не приветствуются — поэтому может возникнуть ситуация, когда при обновлении одного компонента временно перестанет отвечать другой, ожидая завершения операции на первом.
Конечно, при разработке определенных сервисов можно отдать предпочтение не согласованности, а доступности: чтобы в случае обновления или выхода из строя одного сервиса, другие продолжали работу. Но делать это нужно крайне осторожно, чтобы бизнес-логика не принимала решений на основе противоречивой информации.
То есть разработчикам необходимо всегда помнить о проблеме конечной согласованности, находить компромисс между доступностью и согласованностью и предотвращать возможные случаи рассинхронизации данных.
Таким образом, при неоправданном использовании микросервисов многие их преимущества могут быть сведены на нет. Поэтому большинство специалистов советуют начинать с монолита, поддерживая его модульность, а к микросервисам переходить при появлении потребности в них и после проведения предварительной подготовки.
Рассказываем об IT-бизнесе, технологиях и цифровой трансформации
Подпишитесь в соцсетях или по email
Чек-лист: кому не обойтись без микросервисов
- Большая команда: если у вас работает больше 10 человек, команда растет, все сложнее погружать новичков целиком в предметную область, то микросервисы помогут стандартизировать разработку и упростить командную работу.
- Множество взаимодействующих модулей в приложении: если их количество измеряется десятками, однозначно стоит задуматься о микросервисах.
- Объемный код: приложение с многомиллионными строками кода со временем все тяжелее поддерживать и развивать как монолит.
- Долгое время запуска приложений (полчаса и более): переход на микросервисы позволит устранить вынужденные простои и эффективно использовать время разработчиков.
- Различные требования к ресурсам в рамках одного приложения: использование микросервисов идеально в случаях, когда у разных компонентов отличаются требования к ЦП, памяти и так далее.
- Для вашего бизнеса критична непрерывная доставка: если необходимо обеспечить своевременный выход обновлений, микросервисы являются предпочтительным вариантом, так как по скорости развертывания они значительно лучше монолитов.
- Высокий трафик со склонностью к периодическим всплескам нагрузки: микросервисы отлично сочетаются с автомасштабированием и облачной моделью, которые позволят использовать ресурсы только тогда, когда в них есть необходимость.
Что такое микросервисная архитектура
Микросервисная архитектура предполагает разработку и поддержку приложений с использованием небольших модульных сервисов, а не создание программного обеспечения в виде одного большого унифицированного блока кода (монолита). Основная концепция архитектуры в том, чтобы разделить сложное приложение на несколько небольших автономных и управляемых компонентов. Это позволяет повысить гибкость разработки, сократить time-to-market, улучшить отказоустойчивость и облегчить поддержку приложения.
Каждый микросервис имеет собственный набор кода, базу данных и API для взаимодействия с другими сервисами. Они могут быть написаны на разных языках программирования и использовать различные технологии. Взаимодействие сервисов может осуществляться посредством сетевых запросов или сообщений.
Применение микросервисной архитектуры позволяет децентрализовать организацию команд разработчиков. Разные команды могут взаимодействовать с отдельными сервисами и не затрагивать работу соседей. Это способствует ускорению разработки и позволяет сосредоточиться на специфических потребностях бизнеса.
Микросервисная архитектура получила распространение, когда крупным компаниям потребовался более точечный подход к разработке отдельных узлов. Нужно было наращивать отказоустойчивость, но оказалось, что традиционные монолитные IT-системы тяжело масштабировать.
Особенности микросервисной архитектуры
Ключевые особенности микросервисной архитектуры:
- Масштабируемость. Микросервисы могут быть масштабированы независимо друг от друга. Это позволяет распределять нагрузку и ресурсы по сервисам, которые нуждаются в поддержке прямо сейчас.
- Независимость. Каждый сервис полностью автономен и не затрагивает работу соседей. Это означает, что каждый сервис может быть разработан, развернут и обновлен отдельно, без воздействия на остальные компоненты.
- Легковесность. Микросервисы используют легковесные протоколы для взаимодействия между собой, такие как REST или gRPC. Это позволяет сервисам быстро обмениваться данными.
- Гибкость. Микросервисы могут быть разработаны с использованием разных технологий и языков программирования. Это дает разработчикам большую гибкость при выборе технологий для конкретных компонентов системы. Это также позволяет эффективнее управлять командой разработки.
- Управление ошибками. У каждого сервиса есть свое собственное управление ошибками и восстановлением после сбоев. Если один сервис не отвечает, это не приводит к полной остановке системы. Например, сайт продолжит принимать покупки, если микросервис, отвечающий за логистику, будет какое-то время недоступен.
- Легкость развертывания. Микросервисы могут быть легко развернуты на различных серверах или облачных платформах.
- Распределенная разработка. При построении микросервисной архитектуры разработка приложения может быть распределена между несколькими командами. Каждая команда может работать над отдельным сервисом, что ускоряет разработку.
- Легкая замена. Если требуется заменить один сервис, его можно легко заменить, не затрагивая другие сервисы. Это упрощает обновление системы и добавление новых функций.
Несмотря на многочисленные преимущества, микросервисная архитектура также имеет ряд особенностей, которые затрудняют интеграцию такого подхода.
Сложности работы с микросервисами
- Управление. Микросервисная архитектура предполагает работу с большим количеством сервисов, каждый из которых имеет собственную версию и набор зависимостей.
- Комплексность взаимодействия. Микросервисы взаимодействуют друг с другом посредством сетевых запросов. Это может привести к проблемам с производительностью и надежностью, так как каждый сетевой запрос может стать точкой отказа.
- Обеспечение целостности данных. При использовании микросервисной архитектуры данные могут храниться и обрабатываться разными сервисами. Обеспечение целостности данных и синхронизация между сервисами может быть сложной задачей. Например, в финтехе или других сферах, завязанных на быстродействие системы, синхронизировать тысячи транзакций — действительно непростая задача.
- Сложность отладки и тестирования. В микросервисной архитектуре каждый сервис может быть разработан, развернут и масштабирован независимо. Это может затруднять процесс отладки и тестирования, так как необходимо изолировать проблему до конкретного сервиса.
- Уязвимости безопасности. Поскольку каждый сервис имеет доступ к части данных, уязвимость в одном сервисе может привести к компрометации всей системы.
Необходимо учитывать эти риски при проектировании и разработке микросервисной архитектуры, чтобы минимизировать их влияние на систему.
Сравнение микросервисной архитектуры и монолитной
Несмотря на то, что микросервисы — более современный подход к построению архитектуры — это не значит, что он должен внедряться везде, вне зависимости от бизнеса и масштабов приложения. Правильнее говорить о спецификации и стратегических задачах проекта. Решившись распилить монолит, разработчики должны четко понимать, зачем они ввязываются в этот сложнейший процесс.
Рассмотрим сильные и слабые стороны подходов.
Основные архитектурные отличия
Параметры | Монолитная архитектура | Микросервисная архитектура |
Размер и сложность | Монолитная архитектура представляет собой одно большое приложение, в котором все компоненты связаны друг с другом напрямую | В микросервисной архитектуре приложение разбивается на множество микросервисов, каждый из которых отвечает за конкретную функциональность. Это позволяет разделить сложное приложение на более простые и независимые части |
Гибкость и масштабируемость | В монолитной архитектуре, изменения и масштабирование требуют работы со всем приложением, что может быть неэффективным и сложным | Микросервисная архитектура дает большую гибкость при разработке и поддержке приложения. Каждый микросервис может быть разработан, протестирован и развернут независимо от других. Это также облегчает масштабирование, поскольку можно масштабировать только необходимые компоненты |
Надежность | В монолитной архитектуре, если одна часть приложения отказывает, это может привести к отказу всего приложения | В микросервисной архитектуре, если один микросервис перестает работать, остальные микросервисы продолжают функционировать независимо |
Сложность развертывания и управления | Монолитная архитектура может быть более простой в развертывании и управлении, поскольку ее элементы не связаны сложной системой зависимостей | Управление микросервисной архитектурой может быть сложнее, так как требуется управлять несколькими независимыми сервисами и их взаимодействием |
Оба подхода имеют свои сильные и слабые стороны, и выбор между ними зависит от конкретного проекта и его требований.
Готовые кластеры Kubernetes с GPU
Создайте за несколько кликов.