Обновить
10
Дмитрий@brutfooorcer

Пользователь

10
Подписчики
Отправить сообщение

Микросервис это не про размер. Просто, термин так сложился, чтобы от SOA отличать

Так в этом и вопрос. Вы сформировали микросервисную архитектуру, несмотря на то, что у вас есть некий микросервис - ядро. И тут же говорите, что микросервисы - не очень.

многие ставят знак равенства между "имеются (микро)сервисы" и "каждый домен в отдельном небольшом микросервисе, тысячи их!"

Ну так архитектура и там и там микросервисная. Что не пойму претензии. Это примерно как написать "многие ставят знак равенства между " имеется монолит на 50к строк и монолит на 1_000_000 строк".

И мне не нравится выражение "делить на МС". Скорее, отделять от монолита.

Все зависит от контекста. Мне приходилось и делить, и отделять.

И да, для большинства доменов "микросервисы не очень, и есть множество более грамотных подходов"

Дак вы сами привели пример микросервисной архитектуры в своей же статье. Почему не выбрали другой подход, если есть лучше?

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

Но думать, нужен ли для функциональности отдельный МС- надо всегда.

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

А у вас получилось "микросервисы не очень, и есть множество более грамотных подходов".

Щас поищем. Scalability наверняка там есть

Ну так это про масштабируемость. А это явно не слабая сторона микроскрвисов.

Я же написал всë

Вы обосновали выбор микросервисной архитектуры. Почему же вы выбрали именно эту архитектуру, если настолько разочарованы в ней и есть множество решений лучше?

По моему, в плюсах МС никогда не было "повышения быстродействия". Наоборот, всегда пишется о задержке сети.

Как вы можете писать, что "микросервисы переоценены", если сами в предыдущей статье предложили решение на микросервисах?

Хорошая статья, но есть "но": в начале вы жестко критикуете микросервисы, описываете ряд проблем, а потом внезапно первым решением предлагаете микросервисы. Вам не кажется это странным?

Я не имею ввиду, что пример плох, я имею ввиду, что он не коррелирует с начальным тезисом статьи "микросервисы вам не нужны". Нужны, получается, а все описанные минусы вы получите в предложенном вами же решении)

Другой вопрос, что делить на МС надо с умом. Но про это ни слова в начальном тезисе - там только минусы микросервисов. Даже без перечисления плюсов.

Если следовать нарисованной схеме, то не можем, нижний модуль знает о верхнем только интерфейс, который ему надо реализовать.

Он использует только интерфейс, а знает то обо всем модуле.

В том и дело что нет, берется только интерфейс. Задумка в том, что интерфейс меняется намного реже реализации.

Да задумка понятна. Только проблема в том, что далеко не каждый разработчик прочитает доку и поймет, что надо только интерфейсы брать из этого модуля. Еще меньше разработчиков будут проверять, в каком пакете находится класс, который они заинжектили. А еще часть просто насрëт на ваши архитектурные правила, потому что "надо как быстрее". В результате - изолированности нет.

Но так можно сказать и про исходную схему, а что мешает из нижнего модуля использовать верхний?

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

но даже в мартиновской схеме этого

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

Правильное разделение по слоям тоже важно, но это не относится к инверсии зависимостей.

Не относится. Но нарисованная схема ломает это разделение.

Как изменения в верхнем модуле могут по всему проекту расползтись?

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

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

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

Ну у интерфейсы можно использовать не только ради нескольких реализаций, а еще (как минимум) для гибкости и изменяемости приложения.

Например, мы можем понимать, что реализацию в будущем придется поменять (или возможно придется), и интерфейс сразу нам в этом помогает.

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

В импортируемых модулях (библиотеках) интерфейсы дают возможность переопределить реализацию у клиента.

Однозначно, я не упомянул все варианты использования. Но делать интерфейс ради интерфейса - это тоже плохая затея. Но и причин их использовать - не мало.

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

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

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

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

Ну вот и получается, что у вас интерфейс в отдельном слое, а не в вашей квартире (модуле).

Только это не соответствует диаграмме в статье.

Да. В общем, проблема в том, что на диаграмме в чистой архитектуре слой взаимодействия с бд почему то зависит от слоя с бизнес логикой, и находится на самом верхнем уровне.

"Почему то" не в том смысле, что я не понимаю причин и что Мартин хотел этим изобразить. А в том, что в слое, взаимодействующем с БД нам архитектурно ничто не мешает использовать кодовую базу всей нашей бизнес логики. А это как раз то, от чего нас предостерегает стандартная слоистая архитектура.

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

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

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

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

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

А как вам минусы за то, что "не узнал ничего нового"? У меня таких парочка есть, и я прям представляю, как кто то ходит и минусует статьи, потому что уже это знает)

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

Был у меня на работе тест, который падал в выходные дни (там что то с проверкой рабочих графиков). Это был прекрасный тест, который не позволял партизанить по выходным)

Ну смотрите.

Написать тест на конечную точку с использованием wire mock стоит 5-10 минут рабочего времени.

Взамен мы проверяем:

  • Корректность метода.

  • Корректность самого урла.

  • Корректность парсинга переменных пути/хедеров/параметров запроса.

  • Корректность десериализации тела запроса.

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

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

Я не призываю читателей тестировать весь код. И не утверждаю, что это "правильно" или "не правильно". Я просто написал те выводы, которые на данный момент извлек из своего опыта. Не надо представлять это "сектой".

И по поводу "почему автор как достижение говорит про вот такие вещи, что стало меньше ошибок по невнимательности " - хоть я и не пытался преподнести это как "достижение", а лишь указал один из плюсов тестирования, однако: а разве это не достижение?)

Информация

В рейтинге
Не участвует
Откуда
Россия
Работает в
Зарегистрирован
Активность

Специализация

Бэкенд разработчик
SQL
Java
Docker
RabbitMQ
Apache Kafka
Spring Boot
REST
Hibernate
Java Spring Framework
PostgreSQL