Комментарии 21
Архитектура — это всё, что критично для долговременного успеха системы.
Техническая архитектура — это всё, что критично для долгосрочного успеха системы на уровне технологий
Поэтому, начинать надо всё же с понимания желаемых архитектурных свойств и параметров проекта, а не с этих ваших компонентов
1. Производительность
2. Масштабируемость
3. Надежность
4. Доступность
5. Сопровождаемость
6. Безопасность
7. Расширяемость
8. Тестируемость
9. Наблюдаемость
10. Стоимость
Я бы разделял отделные продуктовые проекты и архитектуру системы. Проекты все таки ограничены по времени и делаются на некой архитектуре, если это только не новый продукт требующий создания новой архитектуры. И на одной системе может реализовываться множество проектов.
Вы пишите
начинать надо всё же с понимания желаемых архитектурных свойств
Но как понять какие свойства желаемые? Тут и приходится разбираться, а какие цели у бизнеса, какие проекты ещё могут возникнуть ближайшее время. Это я как раз и описываю в главе "Описание проблемы".
Другой вопрос, а когда вообще стоит задаться вопросом полного перепроектирования архитектуры? Не будем же мы при необходимости например добавления новой фичи этим заниматься каждый раз. Поэтому я описал это раньше в главе "С чего начинается проектирование" и мне показалось логичным начать именно с этого.
Инфоцыганство ака консалтинг надоело уже. Живые примеры давай!
Живые примеры не работают, когда собеседник заранее решил, что это — "инфоцыганство". Уважайте чужой труд — это хотя бы минимально прилично. А вы как отличаете ценную информацию от "инфоцыганства"?
Фаулер это инфоцыган или нет?
Он писал книги в период когда уже давно не записался практикой
Для меня Фаулер очень авторитетный автор, если вы называете инфоцыганом, то скорее всего вы его просто не поняли. По крайней мере его книга Рефакторинг дала мне много пользы. В любом случае, стоит с критикой относиться к любому автору, и не следовать слепо всем советам.
Если вы с чем то не согласны с фаулером в его книге Рефакторинг, дайте конкретику.
Эти подходы особенно полезны, когда нет жёстких требований к высокой производительности и нет необходимости экономить на железе любой ценой.
???? Тут точно речь про DDD и чисто луковичную архитектуру?)
Микросервис всему голова... Только вот ходят легенды что это обычно куча маленьких монолитов.
Да, так и есть. Микросервис - это не очень удачное название, оно не про размер, и не обязано быть маленьким.
Дело не в размере (я надеюсь). А в попытке уйти от монолита на кучу монолитов поменьше (что якобы позволяет меньше внимание уделять архитектуре кода), ещё и их все надо связать между собой
Я не уверен что понимаю что вы понимаете под кучей монолитов поменьше. Если вы про распределенный монолит, то да, это неудачное разделение и это сделает только хуже. Иногда получается достаточно успешно отделить код в микросервис и получить от этого хороший профит.
Например у нас есть микросервис рассылки уведомлений, которым пользуется множество других доменов (чаты, маркетинг, сохраненные поиски и др.). Он достаточно успешно отделен и позволяет независимо и быстрее деплоить задачи в этом сервисе, запускать тесты связанные только с рассылкой уведомлений, независимо масштабировать контейнеры при росте нагрузки и сама нагрузка на этот сервис не влияет на другие сервисы, кроме сценариев когда происходит рассылка уведомлений.
Если мы говорим только про сложность кода, то для её уменьшения может быть достаточно просто отделить сервис в отдельный модуль внутри одного монолита, и уменьшить связность с остальным кодом. Если связность не получается уменьшить внутри монолите, то и отделение этого кода в микросервис не поможет уменьшить эту сложность.
Поэтому тут вопрос насколько правильно вы подходите к этому отделению.
Я не знаю что такое распределенный монолит. Как по мне история монолит/микросервис полуинфоциганская. До появления докеров никто не называл приложение монолитом, а решение его проблем микросервисом, это веение моды (как и JS везде, но тут не только мода, продвижение языка тоже играет большую роль).
Например у нас есть микросервис рассылки уведомлений, которым пользуется множество других доменов (чаты, маркетинг, сохраненные поиски и др.)
Да, это хороший пример для выделения функционала в отдельный какой-то сервис. Но я это делал на условном рэбите и до повсеместного продвижения микросервисов. Но с другой стороны рассылку можно отделить в отдельный программный модуль рядом с приложением. По сути изменится взаимодействие (был условный gRPC, станет межпроцессным). Мне кажется тут только в вопросе масштабирования и адаптации под нагрузку выигрывает микросервис, а так те же яйца только в профиль.
Скажите, а как на микросервисах с подключением к базе данных? Каждый сервис которому нужна БД пишет свое? (Слышал и про такое) или есть микросервис базы данных в который все ходят?
Мне тоже этот термин "микросервис" не нравится, я уже писал об этом в комментарии выше. Но он к сожалению прижился и что пользуемся тем, что имеем. Он многих сбивает с толку. По моему мнению микросервис это лишь про способ деплоя. Можно было бы это же назвать "отдельное приложение" или просто "сервис". Насколько я понимаю монолит и микросервис это просто попытка разделить две крайности, в одном вся кодовая база находится в одном приложении, а в другом она находится в разных приложения.
По правильному у микросервиса должна быть своя изолированная база данных. Но технически ничего не мешает разработчику использовать в разных микросервисах коннект к одной базе.
Я думаю микросервис называется не в плане размера или значимости кода который он хранит и выполняет, а то что для деплоя этих сервисов используется минимально необходимая инфраструктура для его работы (минимальный набор инструментов в ОС и тп.)
Про базы данных прикольно конечно, в монолите бывает взглянешь на базу из 200 таблиц и только унынием наполняешься, а тут ещё по базам бегай собирай все логику во едино. И получается что на уровне базы (баз данных?) сложнее настраивать бизнес процессы (если это вообще реально, внешние ключи на базу к другому микросервису?:))
Как по мне микросервис это местячковое решение для вывода какого-то общего функционала и возможности докидывать или убавить мощности на лету (но с базами данных конечно беда)
Ну оно ещё позволяет например незвисимо обновлять либы только в отдельной части системы, иметь разный язык программирования, делать функциональные тесты (тестировать АПИ, мокая ответы АПИ других микросервисов, при этом запускать тесты с той же базой данных и др. внутренними сервисами), т.е. тестирровать весь цикл взаимодействия с этим микросервисом, не делая сложный интеграционный тест на всю систему, сужать скоуп тестов и соответственно быстрее их прогонять.
Про либы я говорю "и тому подобное" после ОС :)
При хорошей архитектуре внутри приложения тоже все хорошо мокается и тестируется. Тесты на всю систему и не надо делать, если вы хотите проверить нотификатор.
Как по мне с базами данных самый большой минус этих микросервисов, если принято что надо под каждый сервис свою базу данных, с нетерпением жду обратной волны, когда люди начнут рассказывать что микросервис это не так и круто, в монолите база данных как-то поконсистентней и бизнес логику можно базой данных защищать и покрывать, а не только кодом) как было с NoSQL и SQL например.
Внешние ключи зло, их не надо использовать!!! (Они просто никогда не нужны, можно спокойно писать код без них)
В идеале, конечно, микросервис должен быть достаточно автономен доменно так, чтобы другим сервисам он был нужен как можно меньше
Если у вас есть 3 микросервиса, что ходят в другдружку, дублируют DTO и сильно связаны - это плохо, это должно быть монолитом
Если же у вас 3 микросервиса, которые вообще не ходят в друг дружку - это хорошо
(Очень грубо говоря, конечно)
Я всегда начинаю с того, чтобы понять, как бизнес работал в доцифровые времена, или даже если бизнес нативно ИТ - все равно подумать над тем, как бы это выглядела нецифровая версия этого бизнеса. Какие есть или были бы люди, должности, в каких кабинетах сидели бы эти люди. Какие бы данные друг другу передавали, какие бы данные дублировались, конфликтовали и ТД, как часто бы такие проблемы возникали и как бы они решались.
Это позволяет построить логическую модель и понять, что мы вообще автоматизируем.
А дальше те же проблемы, что и в жизни. Бухгалтерия делает индексацию стоимости товара в своей системе (например система 1С). Далее необходимо донести эту информацию до отдела продаж (обслуживает модули CRM и модуль каталог) - пока информация ещё не дошла, продажники с задержкой будет продавать по старым ценам. То же самое с отделом маркетинга. Это демонстрация естественной проблемы не консистентности данных и для неё в компании уже есть решение.
Далее предположим, что отдел маркетинга придумал систему бонусов для клиентов и дал всем специальные калькуляторы, которые считают скидку для клиента. Но проблема в том, что когда меняется алгоритм предоставления бонуса, все эти калькуляторы нужно собрать, перепрошить и отдать обратно. Это проблема неконстстетности логики, распределенного деплоймента или обратной совместимости.
Модуль - это какой-то логический отдел в компании, какой-то домен: бухгалтерия, охрана труда, отдел продаж, отдел маркетинга. Можно дробить модули над под модули вроде "бонусная программа", "обратная связь" и ТД для модуля "отдел маркетинга".
Монолит - это все отделы в одном лице: и бухгалтерия, и отдел продаж, и отдел маркетинга. Хостит большинство модулей и под модулей в системе. Четкого понимания модулей и под модулей зачастую нет. Реализация по принципу - работает и ладно. Даёт быстрый старт, но при необходимости масштабироваться придется отреылексировать и этот оверхэд часто недооценивают.
Модульный монолит - это когда у лица размножение личности, это всё ещё один человек, но меняя роль с отдела продаж на бухгалтерию, он воспринимает это как отдельную личность. Позволяет быстро передать дела специализированному человеку, когда проявляется необходимость. Даёт оверхэд на рефлексию в начале, но более быстрое масштабирование, если необходимо. Но есть риски ударится в слишком глубокую рефлексию готовясь к масштабированию, когда по факту клиентов ещё 0.
Микросервис - это один отдел со своими знаниями, независимыми базами и ТД. Хостит один или несколько логических модулей. Минимально хостит один под модуль. Как и любом предприятии необходимость в отделах появляется, когда происходит дисбаланс в объеме работы. Т.е. на завод может быть 2 бухгалтера, но 100 рабочих у станка.
RPC - это когда отделы между собой общаются по телефону по внутренней сети или просто ходят ногами друг к другу. Если в отделе несколько человек, можно набрать по короткому номеру и звонок нравится свободному сотруднику (load balancing).
Message Broker - это внутренняя почтовая служба. Когда отдел бухгалтерии оставляет "приказ об изменении стоимости товара" в почтовом ящике, брокер обучен, в какие отделы нужно это доставить.
Outbox - записал в ежедневнике или повесил стикер и переводчески просматриваешь заметки или стикеры.
Поэтому в коде нужно налаживать коммуникации между модулями, а не инстансами сервисов. Сегодня модуль часть монолита, завтра часть макросервиса под отдел/домен, послезавтра часть модуль вынесен в микросервис для точечного горизонтального масштабирования. В идеале когда меняется модель хостинга модуля просто обновить service discovery и все.
Вот и вся архитектура. Осталось только во всем этом разобраться. Чем лучше разобрались в том, что происходит сейчас и куда движется бизнес - тем лучше архитектура. Если бизнес сам не знает, что происходит и куда он движется (а такое не редкость), то просто точно так же действуете по наитию, наитие будет рекомендовать вам самый короткий путь. Можно подсказать бизнесу, что вот мы видим по метрикам, что есть бутылочное горлышко в том, что отдел продаж постоянно звонит в отдел маркетинга, чтобы что-то уточнить и, а можно просто по внутренней почте уведомления отправлять (условно).
Вывод: подробили на модули, решили, надо ли этому модулю отдельный специализированный исполнитель (машина / человек) или можно объединить пару модулей в одном исполнителе (машина / человек) и задали конфигурацию кубера.
Мой опыт проектирования архитектуры