Монолитная архитектура что это
Лучшая архитектура для MVP: монолит, SOA, микросервисы или бессерверная. Часть 1
В ноябре OTUS запускает новую образовательную программу «Архитектор ПО», в связи с этим подготовили серию публикаций для будущих студентов курса и читателей нашего блога.
Создание нового продукта всегда связано с риском. И выбор правильной архитектуры — важный шаг на пути успеху. Если вы выбираете между монолитной, сервис-ориентированной, микросервисной и бессерверной архитектурой, этот пост поможет вам сделать правильный выбор.
Монолитная архитектура
Монолит — это древнее слово, обозначающее огромный каменный блок. Хотя этот термин широко используется сегодня, представление остается одинаковым во всех областях. В программной инженерии монолитная модель относится к единой неделимой единице. Концепция монолитного программного обеспечения заключается в том, что различные компоненты приложения объединяются в одну программу на одной платформе. Обычно монолитное приложение состоит из базы данных, клиентского пользовательского интерфейса и серверного приложения. Все части программного обеспечения унифицированы, и все его функции управляются в одном месте. Давайте посмотрим на структуру монолитного программного обеспечения в деталях.
Монолитная архитектура удобна для работы небольших групп, поэтому многие стартапы выбирают этот подход при создании приложения. Компоненты монолитного программного обеспечения взаимосвязаны и взаимозависимы, что помогает программному обеспечению быть самодостаточным. Эта архитектура является традиционным решением для создания приложений, но некоторые разработчики считают ее устаревшей. Тем не менее, мы считаем, что монолитная архитектура является идеальным решением при некоторых обстоятельствах.
Несмотря на то, что у нас был положительный опыт использования микросервисов в Google, мы [в Scaylr] пошли по монолитному маршруту, потому что наличие одного монолитного сервера предполагает меньше работы для нас как для двух инженеров.
Стивен Червински, руководитель отдела проектирования в Scaylr
Чтобы выяснить, подходит ли это решение для вашего бизнеса, давайте рассмотрим его плюсы и минусы.
Плюсы монолитной архитектуры
Упрощенная разработка и развертывание
Есть много инструментов, которые вы можете интегрировать для облегчения разработки. Кроме того, все действия выполняются с одним каталогом, что упрощает развертывание. Благодаря монолитному ядру разработчикам не нужно развертывать изменения или обновления по отдельности, поскольку они могут сделать это сразу и сэкономить много времени.
Меньше сквозных проблем
Большинство приложений зависят от множества межкомпонентных задач, таких как контрольные журналы, ведение логов, ограничение скорости и т. д. Монолитные приложения гораздо легче учитывают эти вопросы благодаря своей единой кодовой базе. К этим задачам проще подключать компоненты, когда все работает в одном приложении.
Лучшая производительность
При правильной сборке монолитные приложения обычно более производительны, чем приложения на основе микросервисов. Например, приложению с микросервисной архитектурой может потребоваться выполнить 40 вызовов API для 40 различных микросервисов чтобы загрузить каждый экран, что, очевидно, приводит к снижению производительности. Монолитные приложения, в свою очередь, обеспечивают более быструю связь между программными компонентами благодаря общему коду и памяти.
Минусы монолитной архитектуры
Кодовая база со временем становится громоздкой
С течением времени большинство продуктов продолжают разрабатываться и увеличиваются в объеме, а их структура становится размытой. Кодовая база начинает выглядеть действительно громоздко и становится трудной для понимания и изменения, особенно для новых разработчиков. Также становится все труднее находить побочные эффекты и зависимости. С ростом кодовой базы ухудшается качество и перегружается IDE.
Сложно внедрять новые технологии
Если в ваше приложение необходимо добавить какую-то новую технологию, разработчики могут столкнуться с препятствиями для на пути внедрения. Добавление новой технологии означает переписывание всего приложения, что является дорогостоящим и требует много времени.
Ограниченная гибкость
В монолитных приложениях каждое небольшое обновление требует полного повторного развертывания. Таким образом, все разработчики должны ждать, пока это не будет сделано. Когда несколько команд работают над одним проектом, гибкость может быть значительно снижена.
В итоге
Монолитная модель не устарела, и в некоторых случаях она по-прежнему прекрасно работает. Некоторые гигантские компании, такие как Etsy, остаются монолитными, несмотря на сегодняшнюю популярность микросервисов. Архитектура монолитного программного обеспечения может быть полезной, если ваша команда находится на начальной стадии, вы создаете непроверенный продукт и не имеете опыта работы с микросервисами. Монолит идеально подходит для стартапов, которым необходимо как можно быстрее запустить продукт в эксплуатацию. Однако некоторые проблемы, упомянутые выше, идут рука об руку с монолитной архитектурой.
Сервис-ориентированная архитектура (далее SOA — service-oriented architecture) — это стиль архитектуры программного обеспечения, который предполагает модульное приложение, состоящее из дискретных и слабосвязанных программных агентов, которые выполняют конкретные функции. SOA разделяет компоненты по двум основным ролям: поставщик и потребитель сервисов. Обе эти роли могут играть программные агенты. Концепция SOA заключается в следующем: приложение может быть спроектировано и построено таким образом, что его модули легко интегрируются и могут быть легко использованы повторно.
Плюсы SOA
Повторное использование сервисов
Из-за автономной и слабо связанной природы функциональных компонентов в сервис-ориентированных приложениях эти компоненты можно повторно использовать в нескольких приложениях, без влияния на другие сервисы.
Легкость в сопровождении
Поскольку каждая служба программного обеспечения является независимой единицей, ее легко обновлять и поддерживать, не затрагивая другие службы. Например, крупными корпоративными приложениями легче управлять, когда они разбиты на службы.
Более высокая надежность
Службы легче отлаживать и тестировать, чем огромные куски кода, как в монолитах. Это, в свою очередь, делает продукты на основе SOA более надежными.
Параллельная разработка
Поскольку сервис-ориентированная архитектура разбита на прослойки, она поддерживает параллелизм в процессе разработки. Независимые сервисы могут разрабатываться параллельно и быть завершены одновременно.
Минусы SOA
Сложность в управлении
Основным недостатком сервис-ориентированной архитектуры является ее сложность. Каждый сервис должен обеспечивать своевременную доставку сообщений. Количество этих сообщений может превышать миллион за один раз, что затрудняет управление всеми службами.
Высокие инвестиционные затраты
Разработка SOA требует значительных предварительных инвестиций в человеческие ресурсы, технологии и разработку.
Дополнительная нагрузка
В SOA все входные данные проверяются до того, как один сервис взаимодействует с другим сервисом. При использовании нескольких сервисов это увеличивает время отклика и снижает общую производительность.
В итоге
SOA лучше всего подходит для сложных корпоративных систем, например банковских. Банковскую систему чрезвычайно сложно разделить на микросервисы. Но монолитный подход также не годится для банковской системы, так как одна часть может повредить все приложение. Лучшее решение — использовать подход SOA и организовать сложные приложения в изолированные независимые сервисы.
На этом мы завершаем первую часть перевода, а о микросервисах и бессерверной архитектуре поговорим во второй части материала.
Монолитная архитектура. Традиционный метод разработки приложений
Выражение «монолитная архитектура» сразу ассоциируется со словом «монолит». А монолитом еще с давних пор называют большой единый блок из камня или бетона. Монолит — это что-то большое и единое, имеющее общую и мощную структуру. Монолит — это сила и на века.
В программировании «монолитная архитектура» также подразумевает наличие общей и единой платформы, где сконцентрированы все компоненты одной программы. Сколько бы н и насчитывалось подобных компонентов, все они унифицированы и при этом управляются из одного места. В этом и определяется сила «монолитных» приложений.
Монолитная архитектура
Многие современные стартапы выбирают именно монолитную архитектуру приложения, потому что она комфортна при работе небольшими группами разработчиков. При ее использовании все компоненты программы взаимосвязываются и взаимозаменяются — это помогает развивать программу автономной и самодостаточной. Монолитная архитектура считается традиционной и проверенной при разработке приложений, но в то же время многие разработчики считают такой подход в реализации приложений старомодным и уже никуда не годным.
Чтобы понимать, подойдет ли вам такой способ разработки или нет, нужно рассмотреть достоинства и недостатки монолитной архитектуры.
Д остоинства монолитной архитектуры
Простая разработка и простой запуск программы. Из-за того, что вся разработка сконцентрирована в одном месте, легче интегрировать инструменты для облегченной разработки, те же каталоги или библиотеки. Плюс при необходимости изменить элементы программы не нужно вносить изменения по отдельности в разных местах — все делается в одном месте.
Сквозные проблемы практически отсутствуют. Большое количество приложений имеют зависимость от задач, которые совершаются между компонентами программы: логи, ограничения скорости, контрольные журналы и т. д. При монолитной архитектуре эти проблемы практически отсутствуют, так как все сконцентрировано в одном коде и все работает в одном приложении.
Недостатки монолитной архитектуры
Большой объем кода. Если разрабатываемый продукт довольно большой и постоянно масштабируется, то со временем его код разрастается до огромных размеров. Это утяжеляет его понимание и дальнейшее обслуживание. Плюс может наступить момент, когда код будет «перегружен» и потеряет от этого свое качество.
Сложно модернизируется. Иногда нужно добавить в приложение какую-то новую «фишку». При монолитной архитектуре можно столкнуться со множеством препятствий, чтобы это реализовать. Потому что в некоторых случаях добавить какую-то «фишку» означает полностью переписать приложение. А это долго и дорого.
Заключение
Монолитная архитектура хоть и «старая» по своему происхождению, но до сих пор актуальн а и используется многими компаниями. Такая архитектура идеально подходит для стартапов и разработок:
когда нужно быстро развернуть небольшое приложение;
когда создается непроверенный продукт и нужно его быстро создать, чтобы протестировать;
когда просто нет опыта работы с микросервисами;
если изначально известно, что приложение не будет разрастаться до колоссальных масштабов;
если в приоритете разработки программного обеспечения наход я тся именно скорость его работы и производительность.
Поэтому перед использованием монолитной архитектуры нужно все тщательно взвесить. Иногда продумывают такой ход: запуск приложения осуществляют при использовании монолитной архитектуры, а чуть позже, если оно «зашло» пользователю, дробят приложения на микросервисы для удобного масштабирования, тем самым меняя его архитектуру.
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
Микросервисы, скалы и гигантские приложения
Как работает мозг разработчика? Очень просто и логично. Например, когда команда разрабов садится за написание новой программы, чаще всего естественным образом выбирается самый простой способ организации кода. А именно — свалить все функции и фичи в одну большую кучу.
Нет, конечно, в коде будет определенная структура. Функции и классы будут аккуратно разбиты на файлы и пакеты, и все это (возможно) будет разложено по папочкам. В итоге на выходе получится набор функций, красиво и логично распиханный по сотням текстовых файлов. И код из одного файла легко может вызывать код из другого файла, без каких-либо ограничений.
Такую структуру очень удобно использовать — написал компонент, закинул его в нужную папку и дальше повторно используешь в других частях системы. Живое воплощение инженерного принципа DRY — don’t repeat yourself — «не пиши код для решения задачи дважды, используй уже написанное».
Такая организация кода (когда все в одном месте) называется «монолитной архитектурой». Конечно, в этой монолитной архитектуре есть свои неоднородности в виде пакетов, файлов и модулей. Но в целом такой код — это огромная скала, состоящая из прожилок, кристалликов и других включений. В скале видно некоторую внутреннюю структуру — но это все же скала. Монолит.
Типичные проблемы с монолитами
Стукнешь здесь — треснет там. Любой первобытный человек знает — стукнув по скале или отпилив кусок, можно вызвать трещины в совершенно другой части этой самой скалы.
А мы с вами знаем, что, внеся изменения в одном месте монолитной программы, можно вызвать повреждения в других ее частях. Все дело в том, что компоненты в монолите могут иметь очень сложные и неочевидные взаимосвязи. Классы, вызывающие функции, получающие на вход другие классы, порождающие новые классы, которые должны быть упакованы в функции — ну… вы поняли.
Мы все стараемся так не делать, но иногда так получается. Например, если нужно срочно внести в код незапланированные изменения в бизнес-процессах и технических заданиях. Именно так классы и функции в коде обрастают многочисленными и неочевидными связями, которые легко можно сломать, даже не узнав об этом.
Сложно обрабатывать. Монолитные куски скал большие, тяжелые, твердые, трескаются от любого неловкого движения.
Такая же история с монолитными программами. Попытка изменить что-то в коде может занять массу времени и иметь далеко идущие последствия.
Например, функция, которую вы меняете, может использоваться в ряде других функциональных блоков. И даже если связи между этими блоками вполне очевидны, вам обязательно нужно не забыть проверить и изменить все зависимые блоки. А если с этими блоками связаны еще какие-то – вам придется идти дальше по цепочке, проверять, вносить изменения, проверять, вносить изменения.
Когда упали — трудно поднять. О да, куски скал падают с грохотом, их тяжело поднимать.
Монолитные приложения тоже падают с грохотом, зачастую парализуя все бизнес-процессы в компании. Даже если ошибка была в коде маленькой и незначительной операции, которая нужна 0.01% пользователей, — в случае сбоя может прилечь вся ваша система.
Нужен спец. Ещё бы, не каждый простой охотник на мамонта может выточить из скалы лицо вождя (племени).
С монолитным кодом — та же история. Из-за своей сложности монолитные приложения требуют от инженера глубокого понимания внутреннего устройства кода. Это понимание обретается либо в ходе долгой работы над проектом, либо путем чтения документации к проекту. А документация часто бывает неполной, ошибочной и не отражающей всей нужной информации о системе.
Разделяй и властвуй
Один из подходов, решающий все эти проблемы (а заодно ускоряющий, удешевляющий и упрощающий разработку в целом) — это микросервисы.
Микросервис — это небольшая программа, запущенная на своем сервере и работающая только над одним типом задач. Например, микросервис склада, который предоставляет другим программам данные о запасах товаров в вашем магазине. Или микросервис авторизации, который принимает пользовательские ключи и пароли, а потом решает, давать ли юзеру доступ в систему или нет. Или микросервис отправки СМСок юзерам.
Любую сложную систему можно разбить на множество мелких сервисов, общающихся друг с другом. Разговаривать сервисы могут любым удобным способом: кидая друг другу сырые TCP-пакеты, вызывая методы по HTTP или используя умную и удобную систему доставки сообщений вроде RabbitMQ.
Почему микросервисы — это классно?
Минимум кода. Микросервисы должны быть действительно “микро”. Программного кода в них должно быть реально мало. В идеале ровно столько, чтобы пара программистов могла написать такую функциональность с нуля за 2-7 рабочих дней.
В таком объеме кода любой специалист сможет разобраться за несколько часов и при необходимости полностью переписать за короткий срок. Увольнение важного и опытного сотрудника не затормозит ваш бизнес — другие разработчики легко во всем разберутся.
На лицо понятные, сложные внутри. Все детали реализации сервиса убираются под капот. Снаружи торчит только простой и удобный интерфейс. Например, ваш сервис доставки СМСок умеет отправлять сообщения через 15 каналов связи, балансируя между ними нагрузку, но все эти тонкости не видны снаружи — на вход сервиса поступают лишь номера телефонов и тексты сообщений.
Как бонус такой подход дает возможность писать сервисы на любом языке программирования, удобном команде. Допустим, вы наняли специалиста, пишущего на странном языке Rust. Вам не нужно переучивать его работать, допустим, с языком Go, он просто может написать нужную логику на Rust, упаковать ее в микросервис и дать другим членам команды доступ к фиче.
Гибко и надежно. Допустим, ваше приложение — магазин, состоящий из набора сервисов (склад, обработка платежей, корзина, пользователи, витрина с товарами). И вот в середине рабочего дня у вас отваливается интеграция с платежным шлюзом. В случае с монолитной архитектурой весь ваш магазин может прилечь (а может и нет, но этого вы не узнаете этого до момента самого сбоя).
В случае микросервиса ваш бизнес сможет показывать клиентам товары и формировать корзины с заказами. А в момент оплаты пользователь будет видеть сообщение “Вы сможете оплатить заказ позже”. Как только сервис оплаты оживет, вы уведомите клиентов об этом и часть из них вернется и оплатит заказ. Пусть это не 100% вашей нормальной выручки, но и не 100% убытка, как было бы в случае полного отказа монолитной системы.
А еще вы можете держать две версии микросервиса оплаты, работающих с разными процессинговыми центрами. В случае отказа одного сервиса, вы отправляете все запросы на резервный — и у вас все хорошо.
Легко чинить. Разработка становится прозрачнее, снижаются её сложность и стоимость. Микросервисную архитектуру легко чинить — вы всегда точно знаете, что и где сломалось. Нет данных о запасах товаров – чиним склад. Не пришла смска – чиним смски.
Кода в сервисе мало, поэтому найти проблему всегда легко. А еще такая архитектура — эталон подхода DRY (не пиши код дважды).
Монолитная vs Микросервисная архитектура
Что такое монолитная архитектура?
Монолитное приложение (назовем его монолит) представляет собой приложение, доставляемое через единое развертывание. Таким является приложение, доставленное в виде одной WAR или приложение Node с одной точкой входа.
Пример
Давайте представим классический интернет-магазин. Стандартные модули: UI, бизнес-логика и дата-слой. Возможны способы взаимодействия с сервисом: API REST и веб-интерфейс.
При построении монолита все эти вещи будут управляться внутри одного и того же модуля. Я не написал «один и тот же процесс», так как это было бы неверно для сценариев, в которых несколько экземпляров нашего модуля будут работать для более высоких нагрузок.
Рассмотрите пример на следующем рисунке, где все части находятся в одном и том же модуле развертывания:
Достоинства
Большим преимуществом монолита является то, что его легче реализовать. В монолитной архитектуре вы можете быстро начать реализовывать свою бизнес-логику, вместо того чтобы тратить время на размышления о межпроцессном взаимодействие.
Еще одна вещь — это сквозные (E2E) тесты. В монолитной архитектуре их легче выполнить.
Говоря об операциях, важно сказать, что монолит прост в развертывании и легко масштабируется. Для развертывания вы можете использовать скрипт, загружающий ваш модуль и запускающий приложение. Масштабирование достигается путем размещения Loadbalancer перед несколькими экземплярами вашего приложения. Как вы можете видеть, монолит довольно прост в эксплуатации.
Теперь давайте рассмотрим негативный аспект монолитной архитектуры.
Недостатки
Монолиты, как правило, перерождаются из своего чистого состояния в так называемый «большой шарик грязи». Вкратце это описывается как состояние, возникшее, потому что архитектурные правила были нарушены и со временем компоненты срослись.
Это перерождение замедляет процесс разработки: каждую будущую функцию будет сложнее развивать. Из-за того что компоненты растут вместе, их также необходимо менять вместе. Создание новой функции может означать прикосновение к 5 различным местам: 5 мест, в которых вам нужно написать тесты; 5 мест, которые могут иметь нежелательные побочные эффекты для существующих функций.
Ранее я говорил, что в монолите легко масштабировать. Это действительно так до тех пор, пока он не перерастёт в «большой шарик грязи», как упоминалось ранее. Масштабирование может быть проблематичным, когда только одной части системы требуются дополнительные ресурсы, ведь в монолитной архитектуре вы не можете масштабировать отдельные части вашей системы.
В монолите практически нет изоляции. Проблема или ошибка в модуле может замедлить или разрушить все приложение.
Строительство монолита часто протекает с помощью выбора основы. Отключение или обновление вашего первоначального выбора может быть затруднительным, потому что это должно быть сделано сразу и для всех частей вашей системы.
Что такое микросервисная архитектура?
В микросервисной архитектуре слабо связанные сервисы взаимодействуют друг с другом для выполнения задач, относящихся к их бизнес-возможностям.
Микросервисы в значительной степени получили свое название из-за того, что сервисы здесь меньше, чем в монолитной среде. Тем не менее, микро — о бизнес-возможностях, а не о размере.
По сравнению с монолитом в микросервисах у вас есть несколько единиц развертывания. Каждый сервис развертывается самостоятельно.
Пример
Давайте вновь рассмотрим в качестве примера Интернет-магазин.
Как и раньше, у нас есть: UI, бизнес-логика и дата-слой.
Здесь отличие от монолита состоит в том, что у всех вышеперечисленных есть свой сервис и своя база данных. Они слабо связаны и могут взаимодействовать с различными протоколами (например, REST, gRPC, обмен сообщениями) через свои границы.
На следующем рисунке показан тот же пример, что и раньше, но с разложением на микроуслуги.
Каковы преимущества и недостатки этого варианта?
Достоинства
Микросервисы легче держать модульными. Технически это обеспечивается жесткими границами между отдельными сервисами.
В больших компаниях разные сервисы могут принадлежать разным командам. Услуги могут быть повторно использованы всей компанией. Это также позволяет командам работать над услугами в основном самостоятельно. Нет необходимости координировать развертывание между командами. Развивать сервисы лучше с увеличением количества команд.
Микросервисы меньше, и благодаря этому их легче понять и проверить.
Меньшие размеры помогают, когда речь идет о времени компиляции, времени запуска и времени, необходимом для выполнения тестов. Все эти факторы влияют на производительность разработчика, так как позволяют затрачивать меньше времени на ожидание на каждом этапе разработки.
Более короткое время запуска и возможность развертывания микросервисов независимо друг от друга действительно выгодны для CI / CD. По сравнению с обычным монолитом он намного плавнее.
Микросервисы не привязаны к технологии, используемой в других сервисах. Значит мы можем использовать лучшие технологии подгонки. Старые сервисы могут быть быстро переписаны для использования новых технологий.
В микросервисах изолируемые разломы лучше по сравнению с монолитным подходом. Хорошо спроектированная распределенная система переживет сбой одного сервиса.
Недостатки
Все звучит довольно хорошо, но есть и недостатки.
Распределенная система имеет свою сложность: в ней вам приходится иметь дело с частичным отказом, более затруднительным взаимодействием при тестировании (тесты E2E), а также с более высокой сложностью при реализации взаимодействия между сервисами.
Транзакции легче проводить в монолите. Решением этой проблемы на микросервисах является Saga Pattern. Хорошее решение, но все же слишком громоздкое для реализации на практике.
Существуют эксплуатационные накладные расходы, а множество микросервисов сложнее в эксплуатации, чем несколько экземпляров сигнального монолита.
Помимо вышеперечисленных сложностей, для микросервисов также может потребоваться больше оборудования, чем для традиционных монолитов. Иногда микросервисы могут превзойти один монолит, если есть его части, которые требуют масштабирования до предела.
Изменения, затрагивающие несколько сервисов, должны координироваться между несколькими командами, а это может быть сложно, если команды еще не имели контактов.
Заключение
Все зависит от вашей организационной структуры. У вас есть 6 команд, которые будут работать над одним продуктом? Микросервисы могут подойти.
У вас есть команда из 3 разработчиков? Вероятно, они будут хорошо строить и поддерживать монолит.
Другими факторами являются скорость изменения и сложность. Высокие темпы изменений и высокая сложность могут быть факторами, которые заставляют выбрать архитектуру микросервиса.
Напротив, когда вы не очень хорошо знакомы с предметной областью, начать с монолита может быть полезно. Просто сделайте себе одолжение и постарайтесь сохранить его модульным. Это облегчит задачу, если вы когда-нибудь решите разделить свой монолит на несколько сервисов.