Comments 72
Ну и банально, сорри за повторение - вся идея о микросервисах не имеет никакого смысла , если все эти "микросервисы" взаимодействуют с общей СУБД.
Пока , я только такие решения встречал. Возможно , в природе есть и другие решения. Но пока архитекторы просто выделяют отдельную БД все кластере и называют это - "мы реализовали микросервисную архитектуру".
Почему? Что на концептуальном уровне мешает микросервисам использовать общую СУБД? Какая разница, хранить свои данные в собственной БД или в своих таблицах в общей БД? Я имею в виду, что отдельному микросервису не нужно знать всю схему БД - достаточно только той части, что относится именно к его данным. А общая БД собирается из фрагментов. Появился новый микросервис - появились новые таблицы в общей БД.
На мой взгляд требование отдельных БД сравнимо с требованием отдельного ЦОДа для каждого микросервиса. Чтобы не было единой точки отказа. Можно, но не обязательно.
Что на концептуальном уровне мешает микросервисам использовать общую СУБД?
Всего 3 слова : "конкуренция за ресурсы". Или другими словами один микросервис влияет на все остальные . Если это считается "микросервисной архитектурой", пусть. Для DBA разницы никакой .
Для микрорешений для 1-10 пользователей и десятком TPS , это вполне работает и они это называют "микросервисы" и очень гордятся.
Когда начинается взрослая работа с сотнями активных сессий и тысячами TPS , начинается ожидаемое "спасите помогите , мы уперлись в СУБД".
Появился новый микросервис - появились новые таблицы в общей БД.
:-)
Всего 3 слова : "конкуренция за ресурсы".
А если BD не является бутылочным горлышком?
"взрослая работа" - это просто подмена понятий. Есть куча приложений, которые уперлись в производительность СУБД, есть куча приложений, которые не уперлись. Вторые - обязательно детские?
Микросервисы обязаны быть изолированными друг от друга и независимыми. Полностью, на всех уровнях, физическом и логическом. Это подразумевает раздельные хранилища данных, сервисы, инфраструктура. Иначе это что-то другое, не микросервисы. Там неприменима CAP теорема, да и вообще вся основная теория проектирования микросервисов, теряют смысл ключевые паттерны. Я бы назвал это "вырожденными микросервисами".
Микросервисы, которые наполняют базу, и которые читают из базы отлично могут совмещать работу с той же самой базой и быть достаточно изолированными друг от друга. И в этом случае скорее всего нет смысла создавать еще одну базу с теми же данными. Можно сделать реплики для повышения производительности в той же базе данных.
ALTER TABLE понадобившийся одному микросервису в этой ситуации легко сломает работу другого. Это не похоже на "быть достаточно изолированными друг от друга".
Один из корректных аналогов того, что Вы описали, это Event Sourcing: когда "пишет в базу" превращается в "отправляет версионированные события", а "читает из базы" превращается в "обрабатывает версионированные события и сохраняет из них нужные данные в собственную БД, из которой в дальнейшем читает".
Другой аналог это когда микросервис "читающий из БД" отправляет запросы на чтение не напрямую в БД, а в API микросервиса "пишущего в БД", который уже проксирует их в БД.
Один микросервис предоставляет API для работы с приложением.
Другой может предоставлять UI для пользователей.
Третий микросервис позволяет выполнять отчеты
Четвертый может быть UI админкой.
Для всех сервисов могут требоваться разные варианты ресурсов. Сервис для отчетов, например, может быть вообще кронджобой, которая не не будет требовать ничего в ожидании события.
И все работают с одной базой. Все могут независимо масштабироваться.
Вот вполне рабочий вариант микросервисов и одной базы.
Микросервисы по сути не имеют права быть полностью независимыми - ведь они по сути являются частью большого приложения, а не независимых приложений.
Основная задача микросервисов - простое масштабирование тех моментов, где может возникать бутылочное горлышко, и упрощение приложение, чтобы было легче разрабатывать новые фичи - тут да, нужна независимость от других микросервисов, но она может соблюдаться грамотным версионированием "коннекторов" и апи.
Этот вариант называется "распределённый монолит". Масштабировать он, конечно, помогает, а вот упрощение при таком подходе - это иллюзия, на самом деле всё становится сложнее, чем в обычном монолите. Рабочий ли это вариант? Безусловно, рабочий. Но, как и обычный монолит, он рабочий только до определённого момента (до которого не все проекты добираются). Основная проблема этого подхода в том, что данный момент (когда он перестаёт быть рабочим) наступает раньше, чем в обычных монолитах.
Микросервисы по сути не имеют права быть полностью независимыми - ведь они по сути являются частью большого приложения, а не независимых приложений.
Это в принципе некорректная точка зрения на микросервисную архитектуру. Корректную точку зрения можно описать вот так: весь интернет целиком можно рассмотреть как пример корректной микросервисной архитектуры. Очевидно, что реализовать функционал всех сайтов в интернете единым (распределённым) монолитом ни у кого бы не получилось - сложность этой задачи на порядки превышает наши когнитивные возможности. А вот сделав у каждого сайта собственную БД и изолировав доступ к его функционалу через API (HTTP), мы получили возможность писать каждый сайт независимо от других. И при этом многие из них активно используют самые разные возможности сторонних сайтов через самые разные API. Изредка, конечно, возникают проблемы совместимости/консистентности и что-то где-то ломается, но в целом вся эта гигантская штука "интернет" работает и даже активно развивается.
При микросервисном подходе мы должны проектировать своё приложение не как "части большого приложения", а именно как кучку "независимых приложений". И чтобы с этим справиться нужен нормальный архитект, который будет постоянно прикладывать достаточные усилия для того, чтобы эта кучка не слеплялась в единый комок с общей БД, потому что новые бизнес-фичи нередко будут тянуть именно в эту сторону. Это сложнее и дороже чем монолит (как обычный так и распределённый), но позволяет проекту выживать далеко за пределами той точки, в которой любые монолиты умирают под собственным весом. И да, микросервисный подход нужен далеко не всем проектам, и без хорошего архитекта он создаст намного больше проблем, чем решит.
Это сложнее и дороже чем монолит (как обычный так и распределённый), но позволяет проекту выживать далеко за пределами той точки, в которой любые монолиты умирают под собственным весом.
Просто рассуждая математически-логически легко доказать что вы не правы. Подумайте сами, если микросервисное (компонентное) решение сложнее и дороже чем микросервисное то в чем же его преимущество?
Дело в том что компонентное решение имеет две фазы проектирования и соответственно разработки. Первая фаза это проектирование и отладка принципов компонентной системы это действительно очень сложно потому что принципы очень не очевидные, очень сложно переключить свое сознание на работу в этих принципах, и не только переключить, а очень внимательно их соблюдать. Но когда эта фаза в основном закончена, когда мы убедились в некоторой гибкости добавления компонент, их включения, отключения, сборки нового решения из компонент, замены версий компонент... когда все это заработало с точки зрения разделения и сборки системы из компонент, добавлять компоненты или апдейтить их совсем не сложно, собственно это и является главным критерием правильно построенной компонентной системы.
Если получилось так что микросервисная архитектура оказывается "сложнее и дороже чем монолит" это как раз и есть "распределённый монолит" с которого вы начали, и я с вами совершенно согласен что:
Масштабировать он, конечно, помогает, а вот упрощение при таком подходе - это иллюзия, на самом деле всё становится сложнее, чем в обычном монолите.
Я под "сложнее и дороже" имел в виду как раз сложность и стоимость первой фазы "проектирования" плюс необходимость наличия компетентного архитекта. Ну и плюс это "первая" фаза очень условно, потому что когда от бизнеса прилетает новое требование, то нередко может оказаться так, что текущая архитектура не позволяет его реализовать без частичного перепроектирования, т.е. мы на эту "первую фазу" ещё не раз будем возвращаться, плюс по результатам этого перепроектирования может потребоваться переписать часть микросервисов, что тоже недёшево. Можно, конечно, попытаться новые требования "запихать ногами" в существующую архитектуру, чтобы не возвращаться к "первой" фазе, но это обычно либо приводит к появлению/добавлению в проект распределённых транзакций/саг, которые тоже заметно увеличивают сложность проекта, либо к слипанию нескольких микросервисов в один (двигаемся обратно к монолиту), либо к доступу нескольких микросервисов к общей БД (двигаемся к распределённому монолиту).
если микросервисное (компонентное) решение сложнее и дороже чем микросервисное то в чем же его преимущество?
Вероятно, Вы хотели сказать "чем монолитное"?
В том, что такой проект можно разрабатывать несколькими независимыми командами сколь угодно долго, он может быть сколь угодно сложным в целом но при этом продолжать "помещаться в голову" разработчиков.
По сути, микросервисное/компонентное решение перемещает сложность с уровня разработчиков на уровень архитекта. Это уменьшает требования к квалификации разработчиков но повышает требования к квалификации архитекта (и очевидно, что ошибки архитекта будут обходиться компании намного дороже, а ошибаются все, что так же повышает цену микросервисного подхода). Мы получаем изоляцию этих компонентов (что уменьшает когнитивную нагрузку на разработчиков и позволяет развивать проект сколь угодно долго без катастрофического падения скорости разработки со временем), но у этой изоляции есть своя цена (проектирование кучи разных API/БД, поддержание совместимости API, накладные расходы на сетевое взаимодействие, ограничения либо сильное усложнение транзакционности, ограничение возможной консистентости данных, дублирований одних и тех же данных в разных БД, усложнение деплоя проекта, усложнение поддержания единых стандартов кода в компании, и т.п.).
По сути, микросервисное/компонентное решение перемещает сложность с уровня разработчиков на уровень архитекта. Это уменьшает требования к квалификации разработчиков но повышает требования к квалификации архитекта
я думаю маленько по другому:
я думаю (я это в принципе на практике наблюдал) компонентное решение не перемещает, а формулирует и стабилизирует требования организации компонентной системы и, действительно, определяет ответственность архитектора за соблюдение и контроль этих требований. Монолитную систему можно определить как систему в которой такие требования просто не сформулированы поэтому ее части проектируются как попало, то есть каждый раз по новой и/или каждый раз заново без учета опыта проектирования уже существующих частей, без того чтобы хотя бы предпринимать попытки унифицировать этот опыт.
Если архитектор руководствуется правилом что не нужны никакие правила, возникает вопрос, а зачем нужен такой архитектор? Архитектор по моему и должен брать на себя определенную сложность с уровня разработчиков и соответствующюю ответственность, иначе зачем нужен архитектор?
Как вы думаете должны рядовые разработчики решать вопросы в областях:
Динамическая компоновка
применения фабрик классов
Повторная применимость компонентов: включение и агрегирование
Маршалинг и синхронизация
...
Если да то вам нужны разработчики с компетенцией архитектора, мне кажется проще найти одного архитектора с компетенцией разработчика, чем N разработчиков с компетенциями архитекторов.
Речь не о том, нужен ли квалифицированный архитект в монолите. Речь о том, что для проектирования микросервисной/компонентной архитектуры квалификация архитекта требуется значительно более высокая, чем для проектирования монолита.
Монолитную систему можно определить как систему в которой такие требования просто не сформулированы поэтому ее части проектируются как попало,
Я не отрицаю, что именно таких монолитов очень много, но я не определяю монолитную систему таким образом. Монолит вполне может быть качественно спроектирован квалифицированным архитектом, что позволит ему прожить дольше, но не решит принципиальную проблему: без полноценной изоляции компонентов (я про собственные API/БД у каждого компонента) каждая новая фича будет увеличивать когнитивную нагрузку на всех разработчиков, что со временем замедлит скорость развития проекта практически до нуля.
Когда на весь монолит есть одна общая БД, то это можно воспринимать как если бы мы в коде все данные держали в глобальных переменных. (БД, по сути, и есть одна большая глобальная переменная.) В начале это удобно и ускоряет разработку, но по мере развития проекта становится очень сложно понимать как работает вся система и как её корректно изменять ничего не ломая.
Ключевая проблема не в отсутствии архитектуры в монолите, а в отсутствии полноценной изоляции частей (в данном случае под "частями" речь о бизнес-фичах, а не, например, архитектурных слоях а-ля "чистая архитектура") монолита друг от друга. Без изоляции увеличивается когнитивная нагрузка на разработчиков (потому что им приходится учитывать больше разных частей и связей между ними), и в какой-то момент они просто перестают понимать как корректно реализовывать новые требования.
А попытка эту изоляцию внедрить в монолит (называя это компонентным подходом или как угодно иначе) по факту требует проектирования полноценной "микросервисной архитектуры", даже если никаких "настоящих" микросервисов не планируется. Потому что "микросервисная архитектура" - это как раз про изоляцию и взаимодействие достаточно самостоятельных и независимых друг от друга частей/фич, и не важно деплоятся они раздельно или как части общего бинарника-монолита. Именно эта изоляция позволяет ограничить рост когнитивной нагрузки на разработчиков и сколь угодно долго продолжать развивать проект с нормальной скоростью. Именно эта изоляция создаёт все те дополнительные сложности, которые я выше описывал как "цену", говоря что этот подход "сложнее и дороже, чем монолит".
Ключевая проблема не в отсутствии архитектуры в монолите, а в отсутствии полноценной изоляции частей (в данном случае под "частями" речь о бизнес-фичах, а не, например, архитектурных слоях а-ля "чистая архитектура") монолита друг от друга.
я с вами абсолютно согласен что изоляция частей это ключевой момент микросервисной архитектуры так же как и авторы древнего фундаментального труда:
компоненты должны удовлетворять двум требованиям. Вопервых, они должны компоноваться динамически. Во-вторых, они должны скрывать (или инкапсулировать) детали своей реализации.
я думаю вы согласитесь что "скрывать (или инкапсулировать)" это синоним нашей с вами изоляции.
Но как видите они еще добавляют требование динамической компоновки, хотя дальше можно прочитать что это не обязательное требование:
Наша конечная цель — предоставить пользователю возможность заменять компоненты во время работы приложения. Хотя эта возможность не всегда реализуется, хотелось бы иметь для нее поддержку. Поддержка замены компонента во время выполнения требует динамической компоновки.
Дело в том что в принципах построения компонентной архитектуры это требование должно быть отражено даже если оно до конца не реализовано в прикладной системе.
Потом вопрос изоляции зачастую упирается в то что объект (часть системы) для изоляции выбрали не правильно, когда пытаются разрезать по живому, образно говоря.
Вот этот талант, увидеть где же в системе проходят границы между частями по которым эту систему можно безболезненно разделить (и значит изолировать части) это и есть талант архитектора и ответственность архитектора, вряд ли эту ответственность можно переложить на рядового разработчика.
Обычно на рядового разработчика перекладывают ответственность за перегруженное взаимодействие между компонентами через границу, которую не правильно определил и установил архитектор, к сожалению.
Согласен, только дополнительно хочу уточнить, что под инкапсуляцией в том контексте почти гарантированно имели в виду исключительно код (API). А для полноценной изоляции нужно ещё дополнительно изолировать и БД.
Вот этот талант, увидеть где же в системе проходят границы между частями по которым эту систему можно безболезненно разделить
А это одна из причин того, что я говорил, что квалификация архитекта микросервисов должна быть выше квалификации архитекта монолита. Помимо этой есть и другие, но эта, пожалуй, основная.
А это одна из причин того, что я говорил, что квалификация архитекта микросервисов должна быть выше квалификации архитекта монолита.
Старые мастера предлагают что-то вроде критерия для проверки своих решений в этом направлении:
Чтобы понять, как это важно /Динамическая компоновка/, лучше всего представить себе приложение, построенное из компонентов, которые не могут объединяться во время выполнения. Если Вы захотите изменить один из компонентов такой системы, Вам придется статически перекомпоновать или перекомпилировать программу и заново разослать ее пользователям. В конце концов, нельзя требовать от конечных пользователей, чтобы они перекомпилировали приложение самостоятельно. Даже если они знают, как это сделать, у них скорее всего нет компоновщика — либо вообще, либо конкретного, необходимого. Приложение, собранное из компонентов, которые надо статически перекомпоновывать каждый раз при замене одного из них, эквивалентно приложению-монолиту
динамическая компоновка это в какой-то степени критерий того, правильно ли вы определили часть для изоляции, если не правильно вы не сможете сделать для этой части динамическую компоновку даже гипотетически, уткнетесь в логические несоответствия.
что под инкапсуляцией в том контексте почти гарантированно имели в виду исключительно код (API).
Тип API там не постулируется, он может быть любой хоть С++, хоть HTTP-шный, принципы универсальны, так же как математика. Реализация инфраструктуры будет меняться в зависимости от средств предметной области.
Есть разделы посвященные распределенным компонентам, из вступления:
С возрастанием производительности и общего значения сетей потребность в приложениях, состоящих из разбросанных по разным местам кусков, будет только повышаться. Компонентная архитектура помогает упростить процесс разработки подобных распределенных приложений. Приложения клиент-сервер — это уже шаг в сторону компонентной архитектуры, поскольку они разделены на две части, клиентскую и серверную.
есть и другие
А какие?
А какие?
В микросервисных проектах есть своя специфика, отличающая их от монолитных проектов. (Это не обязательно в теории, но очень часто встречается на практике.) Например, в микросервисных проектах часто используется куча разных баз данных и брокеры сообщений - соответственно, микросервисному архитекту мало "знать постгрес", ему нужно знать кучу разных БД и понимать, какие БД лучше использовать в каких микросервисах плюс понимать особенности передачи сообщений между микросервисам через конкретный брокер. Помимо этого есть особенности именно распределённых систем и в целом вопросы консистентности данных между БД разных микросервисов. Мониторинг одного монолита и сотни микросервисов - это очень разные задачи. Координация между разными "независимыми" командами. Особенности разных языков программирования, на которых разные команды могут писать микросервисы. Это так, то что сходу пришло в голову, но список вряд ли законченный.
Корректную точку зрения можно описать вот так: весь интернет целиком можно рассмотреть как пример корректной микросервисной архитектуры.
По вашей логике получается, что монолита, как архитектурного решения, не существует вовсе - всё есть микросервисы. Ну или другая крайность - каждый микросервис одновременно является монолитом. Любопытный подход, но не уверен, что корректный.
Можно и так на это смотреть. Монолит означает, что мы должны держать его в голове весь целиком, иначе есть высокий риск что-то упустить и написать некорректный код. И в этом плане нет разницы, работаем мы с большим монолитом или мелким микросервисом. Микросервисная/компонентная архитектура позволяет нам выкинуть из головы реализацию других микросервисов/компонентов нашего проекта, заменив её в голове небольшим API. Ну а соответственно распределённый монолит означает, что в голове его нужно держать целиком (как любой монолит), но при этом сам этот монолит значительно сложнее обычного потому что представляет из себя распределённую систему.

вот как вы думаете это монолит или микросервисы?
Я, в общем, знаю это все, и как работает каждый квадратик знаю, но примерно, а со справочником (с даташитом) я могу решить любую задачу или объяснить чего в этой системе не хватает чтобы решить конкретную задачу, слишком сложную для реализации на этой архитектуре или как эту сложную задачу адаптировать чтобы она всетаки поместилась на этой архитектуре.
Но кроме этой схемы в наличии есть еще несколько десятков схем поменьше, а может и побольше, в зависимости от уровня детализации, о том как взаимодействуют эти квадратики (но уже не все, а только те которые участвуют в работе подсистемы, но некоторые еще разрисованы на квадратики поменьше масштаба) в рамках специальных подсистем, я их тоже в какой то степени знаю примерно все.
Я к тому что большая система всегда состоит из композиции систем, и эту композицию кто-то все равно должен держать у себя в голове в каком-то виде, если такого человека нет, вряд ли система сможет нормально развиваться, то есть рано или поздно она обречена загнуться без архитектора, мне кажется.
Речь не об архитектах. Архитект должен держать в голове весь проект, без разницы монолитный он или микросервисный. Но чтобы весь проект поместился в голову архитект вынужден ограничивать "глубину" погружения в детали каждого "квадратика".
Речь о разработчиках и том объёме соседнего кода, который может сломаться, когда разработчик что-то меняет. Очевидно, что в случае микросервисов что бы разработчик не менял в одном микросервисе другие микросервисы от этого не поломаются. А, значит, разработчик может не держать в голове детали реализации других микросервисов, ему достаточно держать в голове только API тех из них, которые он собирается использовать в рамках текущих изменений своего микросервиса.
У разработчиков тоже есть свои способы ограничивать "глубину" погружения в детали их "квадратиков": пакеты, классы, функции, локальные переменные, области видимости… Но, тем не менее, по мере развития монолитного проекта количество таких деталей, которые невозможно ограничить, постоянно растёт. Глобальные переменные и общая БД - это хорошие примеры того, что нужно всегда держать в голове целиком. Нельзя просто полезть в любую табличку в БД или в глобальную переменную без понимания всего остального кода, который с ней работает - иначе что-то может сломаться. Микросервисы и полноценно изолированные компоненты позволяют контролировать рост количества таких деталей, чтобы он не превысил когнитивные способности разработчиков.
Очевидно, что в случае микросервисов что бы разработчик не менял в одном микросервисе другие микросервисы от этого не поломаются.
То есть если из-за изменений в каком то микросервисе другие микросервисы все таки поломались, мы просто перестаем называть их микросервисами, так что ли? А в чем смысл?
А с чего им ломаться? Это как если от того, что вы у себя на сервере реализовали какой-то сайт и из-за этого сломался гугл или фейсбук.
На практике, когда изменения в одном микросервисе ломают другой - это явный признак того, что у вас не микросервисы, а распределённый монолит.
А с чего им ломаться? Это как если от того, что вы у себя на сервере реализовали какой-то сайт и из-за этого сломался гугл или фейсбук.
а в чем тогда отличие микросервисов от просто экзешников (обычных приложений), которые тоже можно писать совершенно независимо друг от друга? Получается что микросервис это новое модное название приложения (или сайта как в вашем примере), что я упустил?
Приложение/сайт - это бизнес-единица, создающая какую-то ценность для пользователей. Микросервис/компонент - это часть приложения/сайта, связанная с другими такими же частями через API. Некоторые микросервисы могут оказаться достаточно гибкими и универсальными, чтобы предоставлять ценность вне изначального приложения/сайта, в рамках которого они были разработаны - и тогда они сами превращаются в отдельные приложения. Хороший пример: Memcached, который изначально был разработан в рамках проекта LiveJournal, но потом стал самостоятельным проектом.
Так что нет, в общем случае микросервис не является синонимом приложения, но в частных случаях может быть и так.
Что до экзешников, то если разные экзешники используют, к примеру, общий каталог с файлами или общую БД, и изменения в одном из них могут так повлиять на этот общий каталог/БД, что другой экзешник сломается - то эти экзешники не являются независимыми друг от друга: разработчики одного экзешника должны знать как работают другие экзешники, иначе они не смогут реализовать корректно свой. Иными словами то, что это два разных экзешника ещё не означает, что каждый из них это независимое приложение, которое можно разрабатывать отдельно от другого.
Микросервис/компонент - это часть приложения/сайта, связанная с другими такими же частями через API.
Что-то вы меня совсем запутали. Сначала говорили что микросервисы ни как не должны быть друг с другом связаны поэтому они не могут ломать друг друга, теперь пишете что это
часть приложения/сайта, связанная с другими такими же частями через API.
и мне ничего не остается как повторить вопрос в ответ на это:
Иными словами то, что это два разных экзешника ещё не означает, что каждый из них это независимое приложение, которое можно разрабатывать отдельно от другого.
если даже независимые экзешники могут оказаться зависимыми друг от друга и внезапно сломать друг друга, то значит и микросервисы могут также неожиданно сломать друг друга? и мы возвращаемся к вопросу:
если из-за изменений в каком то микросервисе другие микросервисы все таки поломались, мы просто перестаем называть их микросервисами, так что ли?
Получается что если назвать экзешником то это
ещё не означает, что каждый из них это независимое приложение, которое можно разрабатывать отдельно от другого.
а если назвать микросервисом, то означает получается, каким то волшебным образом.
Сначала говорили что микросервисы ни как не должны быть друг с другом связаны поэтому они не могут ломать друг друга, теперь пишете что это "часть приложения/сайта, связанная с другими такими же частями через API".
Все связи между микросервисами/компонентами должны быть только и исключительно через API. Документированный API, сохраняющий совместимость при изменениях.
А когда они связаны через каталог с файлами или БД, работа с которыми осуществляется не в стиле API, а в стиле "творю что мне нужно как мне удобно" (как обычно и принято работать с собственными файлами и БД), то такая связь уже не похожа на API и быстро приводит к тому, что разработчики одного "экзешника" нечаянно ломают работу другого. А чтобы работу другого не ломать они должны знать, как он устроен внутри и учитывать это - т.е. держать в голове реализацию не только своего экзешника, но и всех остальных, которые работают с этим же каталогом/БД.
Честно говоря, это всё настолько очевидно и уже много раз озвучено в соседних комментариях, что у меня появляются сомнения, Вы всё это серьёзно или просто троллите.
у меня появляются сомнения, Вы всё это серьёзно или просто троллите.
я серьезно хотел бы найти понятные, а главное не противоречивые формулировки которые бы меня устроили, но в качестве аргумента я все чаще слышу что все очевидно. Я серьезно пытался выяснить основания этой очевидности с вашей точки зрения. Я тоже чуствую что вопросы получаются как бы с подковыркой, но так всегда получается когда вскрываются противоречия в рассуждениях. Я же по техническим аспектам вам возражаю, просто пытаюсь вскрыть проблемы с логикой по техническим вопросам не более того, разве моя вина, что это в каком то смысле получается? Если вам не интересно как выглядят ваши рассуждения со стороны мы можем просто прекратить обсуждение.
я серьезно хотел бы найти понятные, а главное не противоречивые формулировки которые бы меня устроили
Формулировки для чего конкретно? Можете перечислить?
Если вам не интересно как выглядят ваши рассуждения со стороны
Интересно. Опишите, как они выглядят для Вас, что из всего изложенного Вы услышали/поняли?
я же уже и так два раза повторил:
если из-за изменений в каком то микросервисе другие микросервисы все таки поломались, мы просто перестаем называть их микросервисами, так что ли?
а вы просто игнорируете, это не прикол и не тролинг, это то как технически выглядит ваша логика со стороны. Я понимаю что это не приятно, но это не приятно именно тогда, когда на это нечего возразить.
Да не в этом дело. Это просто звучит настолько дико для меня, что я не воспринял этот вопрос всерьёз. Для меня этот вопрос звучит примерно так: "если наш гусь начал хрюкать, то мы просто начинаем называть его свиньёй а не гусём, так что ли?". Если он хрюкает - то он никогда не был гусём. Если из-за изменений в одном микросервисе ломается другой - они и не были микросервисами.
Полный ответ на Ваш вопрос звучит так: если из-за изменений в одном микросервисе сломался другой, то это значит, что Вы работаете с распределённым монолитом, а не микросервисами, но называли/считали этот распределённый монолит микросервисами. Перестанете ли Вы с этого момента называть его микросервисами или нет - никакого значения не имеет, он как был распределённым монолитом так и остался, как его ни называй.
давайте я вам просто процитирую что для меня очевидно, чтобы у вас не было повода снова меня в чем то обвинять:
Необходимость изоляции клиента от деталей реализации накладывает на компоненты (микросервисы?) ряд важных ограничений. Ниже приведен список этих ограничений:
1. Компонент должен скрывать используемый язык программирования. Любой клиент должен иметь возможность использовать компонент, независимо от языков программирования, на которых написаны тот или другой. Раскрытие языка реализации создает новые зависимости между клиентом и компонентом.
2. Компоненты должны распространяться в двоичной форме. Действительно, поскольку они должны скрывать язык реализации, их необходимо поставлять уже скомпилированными, скомпонованными и готовыми к использованию.
3. Должна быть возможность модернизировать компоненты, не затрагивая уже существующих пользователей. Новые версии компонента должны работать как с новыми, так и со старыми клиентами.
4. Должна быть возможность прозрачно перемещать компоненты в сети. Необходимо, чтобы компонент и использующая его программа могли выполняться внутри одного процесса, в разных процессах или на разных машинах. Клиент должен рассматривать удаленный компонент так же как и локальный. Если бы с удаленными компонентами надо было работать иначе, чем с локальными, то потребовалось бы перекомпилировать клиент всякий раз, когда локальный компонент перемещается в другое место сети.
и на этом разойдемся оставшись каждый при своем мнении.
Я в комментариях к этой статье использовал термин "компонент" подразумевая часть единого приложения (бинарника, экзешника, группы файлов на скриптовом языке распространяемых как единое целое, etc.), которая имеет такой же уровень изоляции от других частей (компонентов), какой у микросервисов. Т.е. у каждого компонента собственный конфиг, собственный API, собственная БД - и другие компоненты из всего этого имеют доступ исключительно к API.
В плане проектирования микросервисной архитектуры нет принципиальной разницы, как именно будут реализованы отдельные части такого приложения - как отдельные микросервисы или как компоненты в рамках общего бинарника. Отличия будут в том, что все компоненты должны быть реализованы на одном языке программирования и их не получится деплоить раздельно - в отличие от микросервисов. Но для многих проектов это и не требуется.
А теперь, прояснив терминологию, пройдёмся по Вашим пунктам:
Компонент должен скрывать используемый язык программирования. Любой клиент должен иметь возможность использовать компонент, независимо от языков программирования, на которых написаны тот или другой. Раскрытие языка реализации создает новые зависимости между клиентом и компонентом.
Нет, это не так. API компонента не обязательно должно быть опубликовано через сетевой интерфейс, оно вполне может быть доступно только другим компонентам в рамках их общего бинарника. Довольно типичная ситуация, когда API микросервиса полностью или частично доступно не только через сетевой RPC, но и через CLI - иными словами API микросервиса/компонента это API его бизнес-логики, а как именно и какие части этого API торчат во внешний мир совершенно не важно.
Кроме того, раскрытие языка реализации никаких дополнительных зависимостей не создаёт.
2. Компоненты должны распространяться в двоичной форме. Действительно, поскольку они должны скрывать язык реализации, их необходимо поставлять уже скомпилированными, скомпонованными и готовыми к использованию.
Это тоже не так. Начиная с того, что существуют скриптовые языки, у которых нет компиляции в бинарник, но это не мешает писать на них микросервисы. И заканчивая тем, что изредка встречаются сервисы встраиваемые в сторонние приложения (по сути они выглядят как обычные библиотеки, но у этих библиотек данные хранятся в собственных файлах/БД). Хороший пример такого "встраиваемого сервиса" - SQLite: по сути это SQL-сервер внутри вашего приложения, с собственными данными, лазить в которые напрямую вашему приложения нельзя, и с API, которое не доступно через сеть.
Должна быть возможность модернизировать компоненты, не затрагивая уже существующих пользователей. Новые версии компонента должны работать как с новыми, так и со старыми клиентами.
Это более-менее верно, но на практике это правило не всегда соблюдается. Иногда поддержка старых клиентов экономически нецелесообразна и от неё отказываются, ломая тем самым работу старых клиентов. Плюс это касается только микросервисов, потому что компоненты, будучи частью общего бинарника, обычно вообще не нуждаются в сохранении совместимости - поскольку все "клиенты" компонента это другие компоненты в том же бинарнике, то несовместимые изменения API фактически сломают компиляцию бинарника пока другие компоненты не будут обновлены на использование нового API - обычно все эти изменения делаются в рамках одного PR, изменяющего реализацию сразу нескольких компонентов. И это - один из больших плюсов использования компонентов вместо микросервисов: возможность атомарно одним PR изменить все связанные между собой части приложения, не тратя ресурсы на поддержку совместимости и не занимаясь сложными танцами с постепенным выкатом нужных версий каждого микросервиса пока все не будут переведены на новую версию API, а потом дополнительными выкатами удаляющими поддержку старой версии API.
Должна быть возможность прозрачно перемещать компоненты в сети. Необходимо, чтобы компонент и использующая его программа могли выполняться внутри одного процесса, в разных процессах или на разных машинах.
Тут различия в наших определениях термина "компонент" становятся настолько очевидны, что по этому пункту я ничего сказать не могу - к моему определению компонентов его просто невозможно применить.
Нет, это не так
вы уж извините, но Дейлу Роджерсону, Найджелу Томпсону(Nigel Tompson), Крейг Брокшмидт (Kraig Brockshmidt), Крейгу Виттенбергу (Craig Wittenberg),... авторам и соавторам этих пунктов я доверяю больше чем вам.
Да я не возражаю, доверяйте. Более того, они вполне могут быть правы, и с пунктами всё может быть хорошо - просто определение термина "компонент" у них совершенно другое, вот и всё.
За историю IT "компонентом" называли множество разных вещей, и до сих пор многие из них актуальны. Без контекста обычно невозможно понять, что имеется в виду. В контексте сравнения с микросервисами напрашивающееся определение термина "компонент" я привёл парой комментариев выше.
Цитируемая в статье книга была написана задолго до появления микросервисов в их современном виде, и, очевидно, у неё совсем другой контекст и совсем другое определение термина "компонент". Вы в статье решили показать, что между современными решениями и решениями полувековой давности есть немало общего - и это правда. Но есть и немало отличий, которые игнорировать столь же недальновидно, как и игнорировать упомянутую Вами "базу фундаментальных, проверенных временем, знаний".
в чем тогда отличие микросервисов от просто экзешников (обычных приложений), которые тоже можно писать совершенно независимо друг от друга?
просто экзешник это просто бинарный файл. В этом определении не указано как его деплоить и запускать.
Микросервис по определению должен не только разрабатываться независимо, но и деплоиться. То есть его рантайм окружение, и его CI/CD пайплайн должны быть незаивисимы.
Например оба эксешника можно руками копировать и запускать на том же хосте. Но в разных директориях, с разными конфигами, чтобы можно было не останавливая один, например удалить перенести на другой хост другой.
просто экзешник это просто бинарный файл. В этом определении не указано как его деплоить и запускать.
некоторые экзешники очень не просто деплоятся с помощью специальной прцедуры установки.
Получается что микросервисы это экзешники которые требуют специальной процедуры установки. Что-то опять не сходится.
То есть его рантайм окружение, и его CI/CD пайплайн должны быть незаивисимы.
вы хотите сказать что в одном рантайм окружении, и его CI/CD пайплайне не могут существовать несколько микросервисов, правильно понимаю?
вы хотите сказать что в одном рантайм окружении, и его CI/CD пайплайне не могут существовать несколько микросервисов, правильно понимаю?
Технически так сделать можно, но в этом просто нет никакого смысла. Да, можно при изменении любого из двух микросервисов прогонять тесты обоих и оба выкатывать на сервер - но зачем? Что до общего рантайма, то зачем делать два бинарника, если они запускаются всегда одновременно на одних и тех же серверах - ведь тогда проще сделать один бинарник, будет тот же результат но меньше суматохи.
Поэтому "не могут существовать" - это некорректное определение, могут. Но так никто не делает, потому что в этом нет смысла. Если уж мы решили сделать два микросервиса, то мы хотим ускорить выполнение тестов тестируя только изменившийся микросервис а не оба, и мы хотим (иметь возможность) выкатывать разные микросервисы на разные сервера и запускать их в разном количестве (в зависимости от нагрузки на каждый из них).
Для микросервиса важно, чтобы его можно было через CI/CD пайплайн вывести отдельно от других микросервисов - то есть независимость деплоймента.
Если пайплайн устроен так, что одновременно деплоится несколько микросервисов - это нарушает изоляцию деплоймента.
Я говорю не про CI/CD утилиту, а про конкретный пайплайн для одного микросервиса.
Если у микросервиса есть общие с другим микросервисом файлы, которые при деплое могут быть изменены - это тоже нарушает независимость деплоймента.
Ну и не важно, эксешник это или нет. Это компонент который можно задеплоить и запустить. А как он реализован - скрипт, бинарник, докер образ - уже второстепенно, главное чтобы каждый микросервис можно было задеплоить независимо от других.
При этом для упрощения релизов, можно сделать какой-то враппер, который может задеплоить одной кнопкой несколько микросервисов, это не мешает, главное чтобы в случае необходимости можно было каждый из них отдельно.
Один микросервис предоставляет API для работы с приложением.
Другой может предоставлять UI для пользователей.
Третий микросервис позволяет выполнять отчеты
Четвертый может быть UI админкой.
Я думаю вы согласитесь с тем что это просто какой то уровень пожеланий, это то чего хотелось бы получить.
Вопрос в том какие принципы позполяют воплотить эти пожелания в жизнь, неужели достаточно только какого то красивого названия, например "микросервисы"?
Может все таки стоит почитать про что-то вроде:
Динамическая компоновка
Фабрика класса
Повторная применимость компонентов: включение и агрегирование
Маршалинг и синхронизация
...
Я считаю, что когда независимость микросервисов возводится в абсолют - это неправильное понимание что такое микросервисы.
Микросервисы были сделаны для того, чтобы облегчить разработку и облегчить масштабирование. Делается это методом, что один микросервис выполняет одну определенную функцию и коммуницирует с другими компонентами.
Изоляция в разработке позволяет довольно быстро переписать конкретный микросервис с нуля, в том числе и на другом языке, с применением других технологий, что было бы сложно в случае монолита.
Изоляция в деплойменте говорит, что изменения в этот микросервис можно внести и вывести на продакшен без изменений где-либо в другом месте. Часто деплоймент может быть полностью автоматизирован.
Насчет того, что микросервисы обязаны иметь изолированные базы, иначе это не микросервис - тут я не соглашусь, это уже просто разные варианты использования микросервисной архитектуры, и тут нет "лучшего". Есть просто разные подходы как этим пользоваться в каждом конкретном случае.
Речь не о лучшем или худшем, любые варианты могут быть рабочими (и good enough) в зависимости от особенностей проекта и команды.
Речь в первую очередь о том, что общая БД означает то, что никакой "изоляции в разработке" у нас уже нет (потому что "изоляция в разработке" означает, что разработчики одного микросервиса могут не думать о реализации других микросервисов, им достаточно доки на их API - а при общей БД этот подход, очевидно, работать не может).
Ну и во вторую очередь речь о том, что желательно использовать общепринятые термины, а не какие красивее звучат. Да, эти термины ещё не на 100% устоявшиеся, но их текущие определения двигаются именно в этом направлении. Общая БД означает либо распределённый монолит, либо что один из наших "микросервисов" не совсем "микро", поскольку состоит из нескольких частей (сервис бизнес-логики, сервис UI, крон-таска) - и все эти части нужно держать в голове при разработке любой из них потому что они недостаточно изолированы друг от друга (даже если пишутся на разных языках и разными командами).
потому что "изоляция в разработке" означает, что разработчики одного микросервиса могут не думать о реализации других микросервисов, им достаточно доки на их API - а при общей БД этот подход, очевидно, работать не может
А почему это вам очевидно? Я имел удовольствие работать с платформой Magento, где множество плагинов (компонентов) добавляло/модифицировало таблицы в одной БД. И это им совершенно не мешало быть достаточно изолированными в разработке. Вплоть до того, что разработчики одного плагина вообще не знали про существование разработчиков другого, но плагины при этом отлично функционировали совместно на одной БД. Это я вам как интегратор говорю.
где множество плагинов (компонентов) добавляло/модифицировало таблицы в одной БД.
если таблицы в одной базе данных не имеют ссылок друг на друга, ничего не "знают" друг про друга, то они вполне себе изолированы друг от друга, с ними можно работать совершенно независимо. Ну разве что могут начать тормозить друг друга при большой интенсивности обращений.
Ну и во вторую очередь речь о том, что желательно использовать общепринятые термины, а не какие красивее звучат
Так в определении микросервисов нигде не указано что в изоляцию включается база данных. Если почитаете банальное определение на википедии, там будет видно что изоляция на уровне разработки и деплоймента, что означает - отдельные кодовые базы и отдельный процесс/под.
Структура базы данных может быть согласована заранее и не меняться. Либо использовать разные таблицы. Либо использовать вьюхи - это уже не есть часть определения. Сервисы должны общаться друг с другом, поэтому в любом случае нужно соблюдать контракты и это уже означает согласование, а не идеальную независимость всего от всего.
То, что за полтора десятка лет распространения микросервисов, начинают переосмысливать и вводить новые вещи... ну так ООП тоже изначально был задуман не так, как используется, и частные споры о том, что и как должно быть в ООП не заменяют базовых определений.
Ок, если опираться на определение в википедии, то обратите внимание на вот это:
In software engineering, a microservice architecture is an architectural pattern that arranges an application as a collection of loosely coupled, fine-grained services, communicating through lightweight protocols.
...
Interfaces need to be designed carefully and treated as APIs.
Не важно, какой механизм коммуникации используется между микросервисами. Обычно это RPC и/или обмен сообщениями, но в теории это может быть и shared memory или общая БД. Конкретный транспорт, который передаёт данные, не имеет значения. Важно только то, что его необходимо трактовать как API. Что означает: документировать и поддерживать совместимость. Ровно так, как это обычно делается для RPC и для формата сообщений.
Я не видел ещё ни одного проекта, в котором бы так использовали БД: явно документировали все таблички и правила как с ними можно работать, гарантированно соблюдали бы эти правила (в идеале это должен автоматически контролировать какой-то инструмент - компилятор, линтер, фреймворк, etc.), а любые несовместимые изменения проводили бы как выпуск новой версии API - т.е. созданием рядом новых v2-табличек и поддержкой одновременно и старых таблиц (для совместимости) и новых. Если так делать - то никаких проблем здесь не будет, соблюдение этих правил позволит гарантировать необходимую для микросервисов изоляцию, и микросервисы работающие таким способом с общей БД вполне уместно считать микросервисами, а не распределённым монолитом.
И причина этого в том, что БД изначально не проектировались и не подходят для такого способа использования. Это возможно реализовать, но это будет сложно и больно. Готовых инструментов для этого я тоже не видел.
Так что в теории общая БД может использоваться не превращая систему в распределённый монолит, но то, как используется общая БД на практике, всегда превращает систему именно в распределённый монолит.
созданием рядом новых v2-табличек
Есть же view. Если вы работали с оракл или постгрес, и не пользовались этим, то зря - как раз для таких случаев.
Опять же, изоляция ради изоляции - не то, что нужно. Основная задача микросервисов - упрощение разработки и масштабирования. Изоляция тут как часть основной задачи. И изоляция базы данных может быть реализована или через документирование структуры или через вьюхи или через независимые базы. Смотря что требуется.
Вот есть у нас микросервис, который занимается созданием отчетов о бизнес процессах. Он берет данные из основной базы. Скажете это не микросервис? Или каким образом нужно для него генерировать данные - копировать всю основную базу? Внедрять экспорт данных в сервис который ведет процессинг? Нет, вполне достаточно чтобы конкретно эти два микросервиса пользовались одной базой. Микросервис отчетов только считывает и в случае изменения структуры базы да, нужно будет поправить оба. С точки зрения архитектуры - это проще и дешевле, чем создавать полную изоляцию ради изоляции.
Есть же view.
Вьюшка - это технический способ который может помочь в обеспечении совместимости. А речь о том, чтобы работу с БД воспринимать как работу с API - начиная с тщательного проектирования и документирования и заканчивая поддержкой этой самой совместимости. Как конкретно это делать - вьюшками или как-то иначе тут вообще не важно.
Микросервис отчетов только считывает и в случае изменения структуры базы да, нужно будет поправить оба. С точки зрения архитектуры - это проще и дешевле, чем создавать полную изоляцию ради изоляции.
Всё верно. Это проще, дешевле, и даже если он сломается то это не критичный функционал (ну, если только эти отчёты не отправляются в налоговую куда их обязательно нужно сдать в заданные сроки).
Никакой проблемы я тут не вижу, за исключением терминологической: это - распределённый монолит, а не микросервисы. Да, конкретно этот вариант распределённого монолита не представляет из себя ничего ужасного, он минимально усложняет разработку и при этом заметно проще и дешевле в реализации чем полноценный микросервисный вариант. Традиционный подход "быстро-грязно" вполне работает в этой ситуации.
На мой взгляд основная проблема этого подхода в том, что глядя на эту реализацию со временем кто-то решит сделать ещё в каких-то местах быстро-грязно в этом стиле. И не все эти места будут настолько же некритичны как этот сервис отчётов. И не все эти места будут работать с чужой БД в режиме read-only. И не все разработчики, которые будут это делать, вообще будут понимать последствия того, что творят. И вот тогда получится вполне традиционный распределённый монолит и много-много боли.
Категорически не согласен с тем, что это "быстро-грязно".
В принципе когда человек максимализирует какую-то идею, это фанатизм, и диалог с таким человеком не выйдет. Так что честь имею.
Категорически не согласен с тем, что это "быстро-грязно".
А аргументировать своё несогласие Вы можете? Или снова просто терминология неустраивает, а по сути возразить нечего?
Я вот такое определение аргументировать могу: это быстро-грязно потому, что для решения этой задачи существуют вполне штатные решения для распределённых систем, не создающие сильных связей между разными микросервисами, более "чистые и гибкие", но при этом их дольше и дороже реализовывать. Например, отправка событий через брокер о нужных изменениях из всех микросервисов, подписка на эти события в сервисе отчётов и создание в сервисе отчётов собственной БД, спроектированной под нужды именно отчётов, заполняемой данными из этих событий. Я не утверждаю, что везде и всегда нужно делать именно так, нередко быстро-грязное решение вроде описанного Вами лучше подойдёт бизнесу/конкретному проекту, но у него есть вполне серьёзные недостатки (уже упомянутый мной) а единственное достоинство в том, что сделать так будет быстрее и дешевле - и это вполне точно описывает суть подхода "быстро-грязно".
В принципе когда человек максимализирует какую-то идею, это фанатизм, и диалог с таким человеком не выйдет.
В целом это верно, только вот где Вы у меня фанатизм увидели? Я же сказал, что "Никакой проблемы я тут не вижу, за исключением терминологической". Или Вы под фанатизмом имели в виду мои настойчивые попытки называть вещи своими именами? Если так, то да, согласен, с моей точки зрения это достаточно важно в таких дискуссиях.
>Микросервисы обязаны быть изолированными друг от друга и независимыми
Но эти два условия логически противоречат друг другу. Изолированные объекты не могут быть независимыми. Тут либо кино, либо мороженное - или у нас объекты независимы (монолит) или они изолированы (микросервисы). Монолит микросервисами быть не может.
Для DBA разницы никакой .
Согласен. Но DBA и не архитектор.
:-)
В Magento именно так и происходит, только на уровне плагинов. И в WordPress так же, насколько я в курсе. Думаю, что и во всех популярных CMS'ках с плагинами точно так же дела обстоят: добавляешь плагин - появляются новые таблицы в БД.
Когда начинается взрослая работа с сотнями активных сессий и тысячами TPS , начинается ожидаемое "спасите помогите , мы уперлись в СУБД".
Так бывает. И не только в микросервисах. Для этого кэши и придумали. Как будто гонять данные между базами микросервисов для их синхронизации (репликации) много лучше?
Дело не в точке отказа, а в изоляции. Границах, которые разработчику одного компонента/микросервиса было бы невозможно (или как минимум очень сложно) нарушить. Потому что когда бизнес торопит сделать фичу всегда есть соблазн срезать угол и взять (а то и изменить) "чужие" данные напрямую, минуя API чужого компонента/микросервиса. Потому что API может нужных данных не давать (или не давать достаточно простым и удобным способом), а внесение изменений в чужое API может потребовать согласования с другой командой, которая отвечает за тот компонент/микросервис и т.п.
Нет никакой проблемы физически хранить таблицы разных компонентов/микросервисов в одном Postgres, но в разных схемах/databases, требующих для доступа к этим таблицам разную аутентификацию. При таком подходе не получится залезть напрямую в чужие данные просто потому, что нет чужого пароля для доступа к ним. А попытка добавить своему компоненту/микросервису в конфигурацию пароль от чужой БД будет крайне заметна на всех уровнях (от ревью этого PR до девопсов которым нужно будет обеспечить передачу "лишнего" пароля при выкате) и обычно будет кем-то успешно заблокирована, даже если разработчик попытается такое реализовать.
Более того, нередко это не вопрос осознанного соблазна "срезать угол", а вопрос того, что не все разработчики понимают архитектуру приложения и искренне не видят в таком подходе (полезть напрямую в "чужие" таблички в общей БД) проблемы. Поэтому и необходимы явные границы, которые будет крайне сложно нарушить как "нечаянно" так и специально.
Поэтому и необходимы явные границы, которые будет крайне сложно нарушить как "нечаянно" так и специально.
вы наверно имеете ввиду "сложно нарушить НЕЗАМЕТНО", то есть чтобы хотя бы некоторое время сохранялась видимость что все нормально работает. То есть границы должны быть явные в том смысле что они делают явным нарушение этих границ.
Кардинальное решение для определения таких границ - иметь возможность отключить отдельный микросервис-компоненту и значит ее функцию и проверить что система все еще работоспособна относительно оставшегося набора функциональности. Достаточно часто эту процедуру можно проделать умозрительно, но для такого типа проверки нужен человек, который очень хорошо знает-понимает архитектуру системы, а еще нужно чтобы он обладал определенным авторитетом и/или полномочиями среди групп разработчиков, чтобы результат проверки не повис в воздухе, а это уже организационный вопрос.
Кардинальное решение - это как раз обычные микросервисы. Сетевое API и собственная БД у каждого микросервиса обеспечивают такой уровень изоляции, который нарушить практически невозможно.
А вот полагаться на мысленные эксперименты квалифицированного эксперта-архитекта - это как раз самый плохой способ, не только потому что ошибаются все включая таких экспертов, но и потому, что у него просто физически не будет возможности выполнять такой анализ для каждого PR.
Нужен простой набор правил, известных всем разработчикам и девопсам, которые они сами смогут легко соблюдать. Например:
Каждый компонент/микросервис имеет доступ только к одному паролю для собственной БД, и что данные каждого находятся в разных БД с разными паролями.
Любое (без исключений) изменение API компонента/микросервиса требует аппрува от архитекта.
Точки в коде, в которые реализован данный функционал (определена конфигурация и API компонента/микросервиса) обычно несложно чётко определить (как правило они всегда в отдельных файлах/пакетах/каталогах), и, при необходимости, настроить автоматическое уведомление архитекта при открытии PR изменяющего эти места в коде.
Более того, я не рекомендую использовать компоненты вместо микросервисов на языках, на которых нет технической возможности надёжно изолировать код компонентов друг от другах. Например, в Go есть возможность изоляции компонентов в рамках одного бинарника с помощью internal/
пакетов, что даёт возможность использовать компоненты вместо полноценных микросервисов не ослабляя уровень изоляции (чтобы один компонент не смог напрямую, минуя публичное API, вызывать код другого компонента). Если же язык или сторонние утилиты (линтеры) не позволяют гарантировать изоляцию, то безопаснее использовать полноценные микросервисы, не смотря на накладные расходы на сетевое API и прочие сложности распределённых систем - это всё-равно лучше, чем превратить проект в очередной "комок грязи".
Любое (без исключений) изменение API компонента/микросервиса требует аппрува от архитекта.
так чтобы выдать аппрув , архитектор должен провести какой-то анализ, но судя по тому что вы написали до этого:
А вот полагаться на мысленные эксперименты квалифицированного эксперта-архитекта - это как раз самый плохой способ
вы не верите в эффективность такого анализа, как же вас понимать?
если есть
простой набор правил, известных всем разработчикам и девопсам
то архитекторы вроде как и не нужны.
А на сколько я знаю простой набор правил просто не получается простым даже когда речь идет о элементарной (казалось бы) загрузке выгрузке компонент в приложении, все равно получается теория уровня высшей математики с элементами диалектики.
Может я неправильно понял Ваш предыдущий коммент, но в моём понимании в нём шла речь о любом изменении системы. Требовать квалифицированного ревью каждого PR на предмет "не нарушили ли мы тут случайно архитектуру" - это тупиковый подход. В моём варианте ревью архитекта требуется крайне редко, только в случае изменения API/конфига, т.е. тех точек, в которых определяются связи между компонентами/микросервисами. Эти связи - как раз область ответственности архитекта, он их изначально спроектировал, и он же должен контролировать их изменение в процессе развития проекта. В идеале в этих точках может даже и кода толком не быть - API обычно описан в swagger.yml
или .proto
-файлах, конфигурация либо в коде (но это просто структура данных) либо в yaml-конфигах оркестратора. Таким образом архитект контролирует именно связи между компонентами, а не реализацию конкретного компонента.
простой набор правил просто не получается простым
Я же выше привёл пример набора из двух правил, что в нём сложного? В реальных проектах обычно добавляется ещё два-три дополнительных условия, специфичных для конкретных условий/языка/etc. но ничего сложного там всё-равно нет (и не должно быть - иначе эти правила не смогут соблюдать).
Может я неправильно понял Ваш предыдущий коммент, но в моём понимании в нём шла речь о любом изменении системы.
да, о разделении на уровни я просто не подумал, с учетом разделения все понятно.
Наверно было бы интересно подискутировать по деталям, но к сожалению у нас нет общего практического примера в рассмотрении.
Я видел API даже написанным в JSON-e, на первый взгляд решение не выглядело адекватным, но у меня не было задачи глубоко вникать почему сделано именно так и можно ли по другому. Судя по тому что я видел раньше, мне кажется что можно, но вполне допускаю что просто кажется.
Вероятно вы не работали в крупном кровавом энтерпрайсе. Место где я сейчас работаю на позиции архитектора, состоит из примерно 2500 подсистем, каждая подсистема это может быть монолит, а может быть сотня микросервисов. И между ними есть взаимодействия. Всё это находится в сотне сетевых сегментах, десятке ЦОД. Как без архитектора что-то делать? Но, справедливости ради, архитектора вообще не лезут в код, основной уровень их работы это С2-С3 по С4 нотации. (есть ещё корпоративные архитектора, они смотрят на всю систему целиком) Мои обязанности это проектирование апи, сети, заказ железа, поддержка паттернов надёжности и куча других сопутствующих задач. И да, никакие интеграции между системами не стартуют до согласования архитектуры решения с аппрувами от всех архитекторов интегрируемых подсистем.
И да, содержать архитекторов это действительно дорого, поэтому мелкие и средние фирмы отдают это на откуп лидам/ТМ-ам.
И да, содержать архитекторов это действительно дорого
дорого содержать только такого архитектора, который не фига ни делает, по моему. Но, действительно, чтобы быть архитектором не обязательно называться архитектором.
Место где я сейчас работаю на позиции архитектора, состоит из примерно 2500 подсистем, каждая подсистема это может быть монолит, а может быть сотня микросервисов.
порядок ваших цифр: 2500х100 микросервисов у меня только вызывают подозрение, что в вашей системе архитекторы допустили ошибку и не одну. Но это конечно только подозрения я же не знаком с вашей системой.
Компания с 1990 года работает, тогда концепции микросервисов ещё в широком смысле не было. И количество микровервисов не 2500х100, а гораздо меньше, думаю на порядок. Суть в том, что такую систему на одних разработчиках невозможно развивать, должны быть люди, которые смотрят сверху и вокруг и эти же люди должны быть технически подкованными. Системные аналитики явно не всегда дотягивают до нужного уровня компетенций.
Дело не в точке отказа, а в изоляции.
Тогда получается, что "микросервисы" это не техническая архитектура, а социальная (административная, организационная). Её появление вызывано не тем, что есть "бутылочные горлышки" в производительности, а тем, что нужно применять в разработке "криворуких индусов" (не все разработчики понимают ... и искренне не видят) Т.е., при достаточной квалификации можно и в одну БД работать ;)
Это правда, но не вся. Микросервисный подход обладает рядом недостатков и рядом преимуществ. Просто в одной ситуации (определяемой компанией/проектом/командой) одни преимущества будут важны, а другие нет, а в другой ситуации будет иначе. Иногда важно именно иметь возможность раздельного деплоя части функционала проекта - ради производительности и/или надёжности. Иногда важно иметь возможность писать разные части функционала на разных языках программирования. Но чаще всего, действительно, основная польза от микросервисного подхода это надёжная изоляция частей проекта друг от друга.
Что до "достаточной квалификации", то в теории - да. Но на практике это не работает. На практике это изредка работает для одного высококвалифицированного разработчика. Но современные проекты редко разрабатываются одним разработчиком, а как только вместо одного начинает работать команда - эффект от процессов (ревью, тесты, вышеупомянутая изоляция которую сложно нарушать, etc.) становится намного сильнее эффекта от квалификации. Так что дело вовсе не в "криворукости". Совсем уж криворуких и изоляция не всегда спасает.
Системы с монобазой на много сервисов встречал только в случаях, когда монолит горе-архитекторы разбивали на микросервисы. Потому что модель данных и базу перепроектировать сложно ж. Самый цимес это когда еще все микросервисы не просто одну базу используют, но еще и общий пакет с орм-оберткой над базой. Идеальный способ просрать ресурсы и время, на выходе получив хлам на порядок хуже, чем был на входе.
Не встречал еще, чтоб микросервисную систему изначально проектировали с одной базой. Хотя верю, что в айти возможно все.
Системы с монобазой на много сервисов встречал только в случаях, когда монолит горе-архитекторы разбивали на микросервисы
Именно так и гордо назвать это - "мы теперь используем микросервисную архитектуру "
верю, что в айти возможно все.
И даже ещё чуть чуть , невозможного.
Поначалу удивляло, потом смешило. Теперь просто не обращаю внимания.
Ибо:
На самом деле, основная цель это заставить пользователя снова и снова платить. Мечта всех разрабов - посадить пользователей на абонентскую плату.
Так вот основной смысл какой бы то ни было сервисной архитектуры (не монолитной) заключается в том, чтобы построить архитектуру таким образом, чтобы иметь возможность передавать пользователю работающей системы усовершенствованные или исправленные части (назовем их сервисы что ли тогда) этой системы в каком-то виде (даже не обязательно бинарники, а как код какого-то класса на интерпретируемом языке, например) чтобы пользователь мог безболезненно подменить такую часть программы в своей работающей системе соблюдая какую-то простейшую и абсолютно понятную с точки зрения этого пользователя процедуру (например примитивное копирование файлов), взамен повторного полного развертывания системы при любом изменении.
Очаровательно, но совершеннейшим образом оторвано от реальности.
Весь смысл микросервисной архитектуры в масштабируемости и отказоустойчивости.
Без учета этих факторов даже и рассуждать о микросервисной архитектуре смысла нет.
"Прелесть" микросервиса не в какой-то мифической частичной доставке изменений (которая, с учетом интеграционного тестирования и прочих прелестей большого энтерпрайза превращается в муки адские), а в том, что отдельные микросервисы можно отдельно масштабировать.
Допустим, у вас есть приложуха, которая какие-то данные в кеше держит и должна быстро отдавать, выполняя элементарные преобразования/выборки. Приложеньке, очевидно, надо много памяти, чтобы кеш содержать. И та же самая приложенька пусть молотит очередь сообщений, тупо конвертируя их, складывая в БД и пересылая куда-то дальше по цепочке.
Итого, как выглядит ваш изумительный монолит: это штука, которой нужно а) много памяти, чтобы хранить кеш, б) много io, чтобы писать в БД и шерстить очереди.
Допустим, в io уперлись. Что делаем? Масштабируем? Окей, увеличиваем количество инстансов вдвое, чтобы io подрастить. Правда, мы при этом только что еще и памяти вдвое больше попросили. А зачем? А в этой ситуации понятнее становится, для чего микросервисы нужны?
Микросервис - это разновидность компонента. Технически компоненты могут выглядеть по разному. Отличие микросервиса от СОМ объекта или, скажем, от просто DLL заключается в том, что микросервисы можно независимо друг от друга масштабировать.
Веб-сервисы существовали задолго до REST. Для них приходилось разрабатывать специальные протоколы поверх TCP/IP. И они должны были бежать внутри специальных контейнеров, которые были сложные, медленные и плохо друг с другом совместимые. Люди с ними мучались лет 10, пока кто-то не сообразил, что вместо специальных веб-контейнеров можно использовать просто HTTP серверы, а вместо специальных протоколов - HTTP с определёнными соглашениями. И все вздохнули с облегчением (за что и назвали это RESTful).
Так что и REST, и микросервисы как таковые это не идиотизм и не дань моде, а ступени развития. Другое дело, что незачем их пускать в ход без необходимости.
Почему микросервисы лучше компонент или как деградируют идеи в IT