Re[7]: Помогите правильно спроектировать микросервисное приложение
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 25.03.25 15:02
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>В этом случае может быть выгодно иметь микросервисы как раз по границам команд. Других адекватных причин использовать MSA я не видел.


S>Ну ещё ограничить failure domain. Чтобы бага в одном углу приложения клала его не целиком, а только блокировала отдельные сценарии.


В managed среда это можно и без микросервисов сделать. А даже в случае unmanaged можно разделить по процессам и использовать unix-sockets\named-pipes для общения между ними в рамках одного сервера, обеспечивая все взаимодействие и синхронизацию разных инстансов (серверов\контейнеров) через базу.

Если говорить failure domain с точки зрения логики приложения, то разделение на микросервисы делает ситуацию только хуже. Так как разработчики одного микросервиса могут внести изменения, ломающие работу других и даже не узнают об этом. Поэтому с точки зрения бизнес-логики идеально чтобы бизнес-процесс начинался и заканчивался в одном микросервисе.

В итоге подходящая модель для MSA — где команды разделены по бизнес-доменам, где все транзакционные бизнес-процессы полностью лежат в ответственности домена. Например закупки, склад, производство, продажи, планирование. Причем это будут дольно большие домены и, соответственно, большие сервисы. Почему их называют "микро-сервисами"&
Re[7]: Помогите правильно спроектировать микросервисное приложение
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 25.03.25 15:32
Оценка: :)
Здравствуйте, ·, Вы писали:

·>Здравствуйте, gandjustas, Вы писали:


G>>В этом случае может быть выгодно иметь микросервисы как раз по границам команд. Других адекватных причин использовать MSA я не видел.

·>В мною виденных трейдинговых системах — везде сабж. Одна команда (~10 девов) пилит пол-сотни приложух, которые разворачивачивется в ~тысячу сервисов на десятках хостов в пятёрке датацентров.
·>И да, сервисы не через REST взаимодйествуют, а через pub-sub сообщения (kafka/29west/mq/fix/аналоги).

Я конечно тоже видел системы, где микросервисов больше чем программистов и пользователей вместе взятых, но при проверке оказывалось что все то же самое можно было бы запились в монолит с меньшими затратами, не потеряв вообще никаких потребительских качеств системы.
Re[8]: Помогите правильно спроектировать микросервисное приложение
От: · Великобритания  
Дата: 25.03.25 16:55
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>·>В мною виденных трейдинговых системах — везде сабж. Одна команда (~10 девов) пилит пол-сотни приложух, которые разворачивачивется в ~тысячу сервисов на десятках хостов в пятёрке датацентров.

G>·>И да, сервисы не через REST взаимодйествуют, а через pub-sub сообщения (kafka/29west/mq/fix/аналоги).
G>Я конечно тоже видел системы, где микросервисов больше чем программистов и пользователей вместе взятых, но при проверке оказывалось что все то же самое можно было бы запились в монолит с меньшими затратами, не потеряв вообще никаких потребительских качеств системы.
Охотно верю. Я лишь рассказал о типах систем, которые ты не видел. Если интересно и есть вопросы, спрашивай.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[8]: Помогите правильно спроектировать микросервисное приложение
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.04.25 05:17
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

G>В managed среда это можно и без микросервисов сделать.

Не очень понятно, что вы имеете в виду. Поддержку AppDomain выпилили (за ненадобностью) из нового дотнета, а в жаве её никогда и не было.
Управляемая среда всего лишь гарантирует отсутствие ошибок типизации и "повисших" ссылок. Всё. Никакой изоляции она из коробки не предоставляет.
Понятно, что она лучше любого анменеджеда хотя бы тем, что в ней нет undefined behavior (если, опять же, придерживаться гигиены и не пользоваться всякими ансейф и около-ансейф вещами).
Но defined behavior недостаточно для ограничения failure domain. Потому что если есть разделяемое состояние, то невозможно гарантировать его целостность при наступлении неожиданных результатов.
Вот у вас есть разделяемая в памяти коллекция, и один поток начал её модификацию, пока второй читает. Ок, мы обеспечили отсутствие гонок, обложив доступ примитивами синхронизации.
Менеджед-среда (более-менее) гарантирует нам то, что при выбросе исключения будут обработаны все блоки finally и, в частности, все удерживаемые блокировки будут отпущены. Но она вовсе не гарантирует нам то, что после отпускания блокировок коллекция придёт в консистентное (с точки зрения прикладных инвариантов) состояние.

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

G>А даже в случае unmanaged можно разделить по процессам и использовать unix-sockets\named-pipes для общения между ними в рамках одного сервера, обеспечивая все взаимодействие и синхронизацию разных инстансов (серверов\контейнеров) через базу.

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

Поэтому сервисная архитектура и появляется как развитие идеи "давайте разведём сервисы по процессам и заставим их взаимодействовать по ограниченным каналам". Выбор JSON over HTTP вместо "proprietary binary protocol over named pipes" обусловлен уже не вопросами надёжности, а вопросами совместимости и готовности к эволюции.
Если мы попытаемся спроектировать свой бинарный протокол со встроенной поддержкой всех нужных negotiations, а также с умением восстанавливаться после сбоев и кэшировать результаты, то у нас получится примерно такой же REST, чутка отличающийся диалектом.

G>Если говорить failure domain с точки зрения логики приложения, то разделение на микросервисы делает ситуацию только хуже. Так как разработчики одного микросервиса могут внести изменения, ломающие работу других и даже не узнают об этом. Поэтому с точки зрения бизнес-логики идеально чтобы бизнес-процесс начинался и заканчивался в одном микросервисе.

Это уже административные вопросы. Вы неявно предполагаете, что единицей тестирования является отдельный микросервис, из-за чего бизнес-процесс, пересекающий границы микросервисов, останется непротестированным.
Но с таким подходом мы налетим на те же проблемы и в монолите — если мы ограничимся юнит-тестами компонентов без интеграционного тестирования получится ровно такой же результат.
А если у нас процесс тестирования построен (хотя бы частично) вокруг бизнес-сценариев, то нам всё равно, сколько там компонентов, сервисов, или микросервисов в нём участвует.
Микросервисы несколько выигрывают по сравнению с другими архитектурами как раз потому, что сокращают возможности по внесению нежелательных зависимостей.
То есть пока у нас всё лежит в монолите, сотрудник команды А имеет возможность подсмотреть в код команды Б, и напрямую завязаться на то, что интерфейс IFoo реализован некоторым классом FooImpl. И вместо того, чтобы обратиться по стандартным каналам к архитекторам команды Б "добавьте мне в IFoo метод по расчёту предварительной цены без заключения сделки", делает даункаст и вызывает потрошки напрямую.
Когда вы распиливаете монолит на процессы и пайпы, такой возможности уже нет — у Foo своё адресное пространство, и мимо протокола к нему обратиться не получится.
Зато можно полезть напрямую в базу "я же знаю, в каких таблицах у них что лежит". В итоге команда Б, полагая себя единоличными владельцами схемы, что-то перекраивает в очередной версии своего сервиса, и код команды А начинает падать, хотя такой же код неделю назад прекрасно работал.

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


Не, это вы как раз рассказываете про SOA, где сервисы всё ещё представляют собой очень крупные блоки. А MSA — это как раз экстремальное развитие SOA, когда мы дробим задачу на ещё более мелкие единицы, которые не реализуют никакой бизнес-процесс, а, скорее, отвечают за некоторые кирпичики этого процесса. Например, у вас есть "ядро" — микросервис, который отвечает за финансовые транзации. Только переводы между счетами, и всё. У него очень жёсткие инварианты, и всё покрыто требованиями регулятора. Поверх этого вы реализуете функциональность типа "Выдача кредитов". Наличие отдельного ядра гарантирует вам, что криворукий джун, разрабатывая код бизнес-процессов "выдача кредита" и "внесение очередного платежа" не напорет с транзакциями и не сломает базовые гарантии типа сохранения суммы всех балансов.
Опять же сбоку этого делается отдельный сервис по оценке рисков, который никак не может сломать поведение бизнес-процесса "рассмотрение кредитных заявок", и в худшем случае у вас какие-то из видов кредитов перестанут выдаваться. Но никаких шансов запороть механику начисления процентов и списания задолженности у этого микросервиса нет.
И так далее — всё строится из параноидально изолированных микрокомпонентов. Один умеет рассчитывать стоимость залогового имущества, другой — умеет управлять статусами залогового имущества. Третий из этих двух собирает бизнес-процесс "переоценка рисков и досрочное истребование кредита в связи с изменением существенных обстоятельств".
Дополнительными бонусами являтся возможность один писать на питоне, другой — на тайпскрипте.

Как-то так.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: Помогите правильно спроектировать микросервисное приложение
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 01.04.25 14:04
Оценка: -1 :)
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>В managed среда это можно и без микросервисов сделать.

S>Не очень понятно, что вы имеете в виду. Поддержку AppDomain выпилили (за ненадобностью) из нового дотнета, а в жаве её никогда и не было.

Ну есть экспериментальные DotNetIsolator [EXPERIMENTAL]

Правда 2 года не изменялась

// Set up an isolated runtime
using var host = new IsolatedRuntimeHost().WithBinDirectoryAssemblyLoader();
using var runtime = new IsolatedRuntime(host);

// Output: I'm running on X64
Console.WriteLine($"I'm running on {RuntimeInformation.OSArchitecture}");

runtime.Invoke(() =>
{
    // Output: I'm running on Wasm
    Console.WriteLine($"I'm running on {RuntimeInformation.OSArchitecture}");
});
и солнце б утром не вставало, когда бы не было меня
Re[9]: Помогите правильно спроектировать микросервисное приложение
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.04.25 07:45
Оценка: 80 (1)
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>В managed среда это можно и без микросервисов сделать.

S>Не очень понятно, что вы имеете в виду. Поддержку AppDomain выпилили (за ненадобностью) из нового дотнета, а в жаве её никогда и не было.
S>Управляемая среда всего лишь гарантирует отсутствие ошибок типизации и "повисших" ссылок. Всё. Никакой изоляции она из коробки не предоставляет.
S>Понятно, что она лучше любого анменеджеда хотя бы тем, что в ней нет undefined behavior (если, опять же, придерживаться гигиены и не пользоваться всякими ансейф и около-ансейф вещами).
Я говорю о том, что вручную выстроенная модульность внутри приложения, на уровне отсутствия ссылок из группы объектов, поддерживается самой managed средой. Без использования ансейфа и разделяемых данных без должной осмотрительности крайне сложно в managed среде во время обработки одного запроса нарушить работу кода, обрабатывающего другие запросы.


S>Но defined behavior недостаточно для ограничения failure domain. Потому что если есть разделяемое состояние, то невозможно гарантировать его целостность при наступлении неожиданных результатов.

S>Вот у вас есть разделяемая в памяти коллекция, и один поток начал её модификацию, пока второй читает. Ок, мы обеспечили отсутствие гонок, обложив доступ примитивами синхронизации.
S>Менеджед-среда (более-менее) гарантирует нам то, что при выбросе исключения будут обработаны все блоки finally и, в частности, все удерживаемые блокировки будут отпущены. Но она вовсе не гарантирует нам то, что после отпускания блокировок коллекция придёт в консистентное (с точки зрения прикладных инвариантов) состояние.
S>Всё, у вас ошибка в одном из "микросервисов" привела к тому, что рантайм стейт всего приложения пришёл в развал. Все остальные будут делать фигню или сыпать ошибками.

Очень хороший кейс.

А давай прикинем как это будет в MSA. там будет точно такая же коллекция в одном из сервисов, и менять её будет не поток, порожденный программистом, а поток порожденный хостом для обработки запроса. А все остальное будет то же самое. И, как в случае монолитного приложения, так и в случае MSA падения как такового не будет. Восстановление после такого falure возможно только сбросом состояния путем насильного перезапуска, например по хелсчеку. Разница в случае MSA будет только в том, что будет перезапущен один маленький сервис, а не толстое приложение. Но при этом весь сценарий работать не будет, пока микросервис с разделяемой коллекцией в памяти не оживет.

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




G>>А даже в случае unmanaged можно разделить по процессам и использовать unix-sockets\named-pipes для общения между ними в рамках одного сервера, обеспечивая все взаимодействие и синхронизацию разных инстансов (серверов\контейнеров) через базу.

S>Всё верно. Если у нас shared state вынесен в "базу", которая предоставляет ACID-гарантии, то у нас масштабы проблемы ограничены.
При горизонтальном масштабировании к этому все и придут обязательно. В принципе грамотный архитектор должен сразу на такое натолкнуть.

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

Опять-таки MSA ничем не помогает в этом случае. Без разницы будет мусор писать в базу микросервис или монолит.

G>>Если говорить failure domain с точки зрения логики приложения, то разделение на микросервисы делает ситуацию только хуже. Так как разработчики одного микросервиса могут внести изменения, ломающие работу других и даже не узнают об этом. Поэтому с точки зрения бизнес-логики идеально чтобы бизнес-процесс начинался и заканчивался в одном микросервисе.

S>Это уже административные вопросы. Вы неявно предполагаете, что единицей тестирования является отдельный микросервис, из-за чего бизнес-процесс, пересекающий границы микросервисов, останется непротестированным.
Так это самые важные вопрос. Я еще раз напомню тезис, который в этой теме и другие коллеги подтверждают: MSA это больше про оргструктуру, а не про архитектуру. В интернетах предлагают "правильную" MSA с разделением микросервисов по разным репозитариям исходного кода. Как в этом случае обеспечить синхронность изменений разных микросервисах, если изменяемый бизнес-процесс затрагивает несколько таких микросервисов?

S>Но с таким подходом мы налетим на те же проблемы и в монолите — если мы ограничимся юнит-тестами компонентов без интеграционного тестирования получится ровно такой же результат.

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

S>А если у нас процесс тестирования построен (хотя бы частично) вокруг бизнес-сценариев, то нам всё равно, сколько там компонентов, сервисов, или микросервисов в нём участвует.

В msa весьма вероятна ситуация, что в принципе невозможно собрать работающее сочетание микросервисов. Я такое на практике видел. Было три микросервиса (А,Б,В) и два процесса(1,2), затрагивающие три сервиса. В один момент было так, что: А/HEAD, Б/HEAD, В/HEAD~1 работал сценарий 1, но не работал 2. А/HEAD, Б/HEAD~1, В/HEAD работал 2, но не работал 1 и при этом же А/HEAD~1, Б/HEAD, В/HEAD также работал 2, но не работал 1.

И каждый разработчик миросервиса доказывал что "work on my microservice" (современный аналог work on my machine)


S>Микросервисы несколько выигрывают по сравнению с другими архитектурами как раз потому, что сокращают возможности по внесению нежелательных зависимостей.

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

S>То есть пока у нас всё лежит в монолите, сотрудник команды А имеет возможность подсмотреть в код команды Б, и напрямую завязаться на то, что интерфейс IFoo реализован некоторым классом FooImpl. И вместо того, чтобы обратиться по стандартным каналам к архитекторам команды Б "добавьте мне в IFoo метод по расчёту предварительной цены без заключения сделки", делает даункаст и вызывает потрошки напрямую.

Доункаст к чему, если у него нет паблик класса, к которому даункастить?

S>Когда вы распиливаете монолит на процессы и пайпы, такой возможности уже нет — у Foo своё адресное пространство, и мимо протокола к нему обратиться не получится.

Тут даже комментировать не буду. В дотнете и жабе полно средств изоляции. При желании даже в JS можно инкапсуляцию сделать, чтобы до потрохов никто не добрался.

S>Зато можно полезть напрямую в базу "я же знаю, в каких таблицах у них что лежит". В итоге команда Б, полагая себя единоличными владельцами схемы, что-то перекраивает в очередной версии своего сервиса, и код команды А начинает падать, хотя такой же код неделю назад прекрасно работал.

Так можно и в базу другого микросервиса полезть. А чтобы этого не было — надо чтобы это были разные репы и фактически было невозможно запустить сервисы на одной машине. А это автоматом означает сложности в тестировании.
В случае единой репы и нормального архитектора — на ревью бить по рукам (или по лицу) за такой код.

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


S>Не, это вы как раз рассказываете про SOA, где сервисы всё ещё представляют собой очень крупные блоки. А MSA — это как раз экстремальное развитие SOA, когда мы дробим задачу на ещё более мелкие единицы, которые не реализуют никакой бизнес-процесс, а, скорее, отвечают за некоторые кирпичики этого процесса. Например, у вас есть "ядро" — микросервис, который отвечает за финансовые транзации. Только переводы между счетами, и всё. У него очень жёсткие инварианты, и всё покрыто требованиями регулятора. Поверх этого вы реализуете функциональность типа "Выдача кредитов". Наличие отдельного ядра гарантирует вам, что криворукий джун, разрабатывая код бизнес-процессов "выдача кредита" и "внесение очередного платежа" не напорет с транзакциями и не сломает базовые гарантии типа сохранения суммы всех балансов.

Я именно об этом и говорю. Знаю один банк где над таким ядром-"микросервисом" трудится команда из 40+ только программистов. То есть ни разу он не "микро", о чем я и говорю. А выдача кредитов это вообще с десяток связанных процессов, на каждом из которых команда в 10+ человек. То есть их тоже "микро" назвать сложно.

Напомню что апологеты микросервисов говорят что микросервис это когда команду можно накормить двумя пиццами, грубо 4-5 человек.

S>Дополнительными бонусами являтся возможность один писать на питоне, другой — на тайпскрипте.

Это какбы единственное неоспоримое преимущество MSA, с которым никто никогда и не спорил.
Re[10]: Помогите правильно спроектировать микросервисное приложение
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.04.25 09:51
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

G>Я говорю о том, что вручную выстроенная модульность внутри приложения, на уровне отсутствия ссылок из группы объектов, поддерживается самой managed средой. Без использования ансейфа и разделяемых данных без должной осмотрительности крайне сложно в managed среде во время обработки одного запроса нарушить работу кода, обрабатывающего другие запросы.

Это понятно, просто "не использовать разделяемые данные" бывает достаточно сложно, кмк. Менеджед-гарантии, конечно, лучше, чем аналоги из неуправляемого мира, где даже и без разделяемых данных можно разломать всё, что угодно, но, увы, я не знаю способов быстро сказать по внешнему виду какого-нибудь кода, использует ли он какие-то разделяемые данные или нет.

G>А давай прикинем как это будет в MSA. там будет точно такая же коллекция в одном из сервисов, и менять её будет не поток, порожденный программистом, а поток порожденный хостом для обработки запроса. А все остальное будет то же самое. И, как в случае монолитного приложения, так и в случае MSA падения как такового не будет. Восстановление после такого falure возможно только сбросом состояния путем насильного перезапуска, например по хелсчеку. Разница в случае MSA будет только в том, что будет перезапущен один маленький сервис, а не толстое приложение. Но при этом весь сценарий работать не будет, пока микросервис с разделяемой коллекцией в памяти не оживет.

Всё верно. MSA не гарантирует безошибочности. MSA гарантирует, что падение не затронет сценарии, в которых микросервис не задействован.

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

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

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

Вопрос открытый. Чего я только не видел в энтерпрайзе, при самых грамотных архитекторах.

G>Опять-таки MSA ничем не помогает в этом случае. Без разницы будет мусор писать в базу микросервис или монолит.

Нет, разница принципиальная. Микросервис физически не может записать в чужую базу кривую запись о переводе денег.

G>Так это самые важные вопрос. Я еще раз напомню тезис, который в этой теме и другие коллеги подтверждают: MSA это больше про оргструктуру, а не про архитектуру. В интернетах предлагают "правильную" MSA с разделением микросервисов по разным репозитариям исходного кода. Как в этом случае обеспечить синхронность изменений разных микросервисах, если изменяемый бизнес-процесс затрагивает несколько таких микросервисов?

Никак — MSA, собственно, и обеспечивает отсутствие синхронности. Это преимущество, а не недостаток.
Изменения в бизнес-процессе накатываются постепенно: сначала мы обучаем новостям самый "нижний" микросервис в топологически отсортированном списке микросервисов, затем — чуть более "верхние".
Изменения в БП становятся видны в тот момент, когда мы выкатываем изменения "корневого" микросервиса, который оркестрирует весь БП.

S>>Но с таким подходом мы налетим на те же проблемы и в монолите — если мы ограничимся юнит-тестами компонентов без интеграционного тестирования получится ровно такой же результат.

G>В msa весьма вероятна ситуация, что в принципе невозможно собрать работающее сочетание микросервисов. Я такое на практике видел. Было три микросервиса (А,Б,В) и два процесса(1,2), затрагивающие три сервиса. В один момент было так, что: А/HEAD, Б/HEAD, В/HEAD~1 работал сценарий 1, но не работал 2. А/HEAD, Б/HEAD~1, В/HEAD работал 2, но не работал 1 и при этом же А/HEAD~1, Б/HEAD, В/HEAD также работал 2, но не работал 1.

G>И каждый разработчик миросервиса доказывал что "work on my microservice" (современный аналог work on my machine)

Это организационная проблема. В монолите все эти команды делали бы ровно то же самое ровно с тем же результатом.
А, ну и, возможно, неудачно были проведены границы между микросервисами. Это — отдельное искусство, настолько редкое, что я, ЕМНИП, видел только одно правильное решение (и с десяток заведомо неверных).

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

Может быть. Я не говорю, что MSA — единственный верный способ деятельности

G>Доункаст к чему, если у него нет паблик класса, к которому даункастить?

Почему вы думаете, что нету?
А если нету — всегда можно запилить reflection. Пытливому уму все средства хороши.

G>Тут даже комментировать не буду. В дотнете и жабе полно средств изоляции. При желании даже в JS можно инкапсуляцию сделать, чтобы до потрохов никто не добрался.

Как раз в JS-то можно. Но, опять же, можно!=делают.

G>Так можно и в базу другого микросервиса полезть.

Невозможно. Базу чужого микросервиса даже не видно. И даже если вдруг чужая база лежит на той же машине, то доступ к ней выдан другому сервис-аккаунту, чем тот, под которым бегает этот микросервис.

G>В случае единой репы и нормального архитектора — на ревью бить по рукам (или по лицу) за такой код.

Это всё хорошо работает до определённых размеров кодовой базы, команды, и уровня ответственности за промахи. Там, где за ошибки принято тюремное заключение или суровые штрафы, делают именно так, не полагаясь на бдительность peer review и личность архитектора.

G>Я именно об этом и говорю. Знаю один банк где над таким ядром-"микросервисом" трудится команда из 40+ только программистов. То есть ни разу он не "микро", о чем я и говорю. А выдача кредитов это вообще с десяток связанных процессов, на каждом из которых команда в 10+ человек. То есть их тоже "микро" назвать сложно.

Так "micro" это же не про размер команды. А про "площадь поверхности".

G>Напомню что апологеты микросервисов говорят что микросервис это когда команду можно накормить двумя пиццами, грубо 4-5 человек.

Хм. Я не очень тесно знаком с апологетами микросервисов, могу чего-то не знать.

G>Это какбы единственное неоспоримое преимущество MSA, с которым никто никогда и не спорил.

Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[10]: Помогите правильно спроектировать микросервисное приложение
От: · Великобритания  
Дата: 02.04.25 10:08
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

G>Я говорю о том, что вручную выстроенная модульность внутри приложения, на уровне отсутствия ссылок из группы объектов, поддерживается самой managed средой. Без использования ансейфа и разделяемых данных без должной осмотрительности крайне сложно в managed среде во время обработки одного запроса нарушить работу кода, обрабатывающего другие запросы.

Гы. Как минимум, память и gc — разделяемые. Так что когда запрос какого-нибудь отчёта для аналитики вдруг роняет по OOM всё сразу, в т.ч. обработку заказов — ничего хорошего.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[11]: Помогите правильно спроектировать микросервисное приложение
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.04.25 11:03
Оценка: +1
Здравствуйте, ·, Вы писали:

·>Здравствуйте, gandjustas, Вы писали:


G>>Я говорю о том, что вручную выстроенная модульность внутри приложения, на уровне отсутствия ссылок из группы объектов, поддерживается самой managed средой. Без использования ансейфа и разделяемых данных без должной осмотрительности крайне сложно в managed среде во время обработки одного запроса нарушить работу кода, обрабатывающего другие запросы.

·>Гы. Как минимум, память и gc — разделяемые. Так что когда запрос какого-нибудь отчёта для аналитики вдруг роняет по OOM всё сразу, в т.ч. обработку заказов — ничего хорошего.
Ничего не мешает в рамках монолитного решения вынести отдельный инстанс для обработки тяжелых запросов и на уровне балансера распределять.

Еще раз повторю тезис: MSA это больше про оргструктуру и следующие за ней технические решения. А все инструменты: докеры, кубернетесы, балансеры, кэши, готовые сервисы хранения и расчетов, вполне можно применять даже если у вас весь ваш код в одной репе, копилируется в один бинарник и запускается в одном контейнере.
Re[12]: Помогите правильно спроектировать микросервисное приложение
От: · Великобритания  
Дата: 02.04.25 11:21
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>Я говорю о том, что вручную выстроенная модульность внутри приложения, на уровне отсутствия ссылок из группы объектов, поддерживается самой managed средой. Без использования ансейфа и разделяемых данных без должной осмотрительности крайне сложно в managed среде во время обработки одного запроса нарушить работу кода, обрабатывающего другие запросы.

G>·>Гы. Как минимум, память и gc — разделяемые. Так что когда запрос какого-нибудь отчёта для аналитики вдруг роняет по OOM всё сразу, в т.ч. обработку заказов — ничего хорошего.
G>Ничего не мешает в рамках монолитного решения вынести отдельный инстанс для обработки тяжелых запросов и на уровне балансера распределять.
Видимо ты тут намекаешь на какую-то принципиальную разницу между SOA и MSA?
Ещё почему-то ты предполагаешь что есть некий один универсальный балансер. А в приложухе может быть REST для аналитики, FIX для заказов и т.п.

G>Еще раз повторю тезис: MSA это больше про оргструктуру и следующие за ней технические решения.

По-моему, ты причину со следствием путаешь.

G>А все инструменты: докеры, кубернетесы, балансеры, кэши, готовые сервисы хранения и расчетов, вполне можно применять даже если у вас весь ваш код в одной репе, копилируется в один бинарник и запускается в одном контейнере.

А зачем обязательно один бинарник? Если деплоймент разный всё равно. Чтобы были многочасовые билды?
Сборка, деплой и перезапуск мелкого сервиса занимает минуты от момента мержа PR. Тогда как типичная выкатка монолита — приятно проведённые выходные.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[13]: Помогите правильно спроектировать микросервисное приложение
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.04.25 14:32
Оценка: +1
Здравствуйте, ·, Вы писали:

·>Здравствуйте, gandjustas, Вы писали:


G>>>>Я говорю о том, что вручную выстроенная модульность внутри приложения, на уровне отсутствия ссылок из группы объектов, поддерживается самой managed средой. Без использования ансейфа и разделяемых данных без должной осмотрительности крайне сложно в managed среде во время обработки одного запроса нарушить работу кода, обрабатывающего другие запросы.

G>>·>Гы. Как минимум, память и gc — разделяемые. Так что когда запрос какого-нибудь отчёта для аналитики вдруг роняет по OOM всё сразу, в т.ч. обработку заказов — ничего хорошего.
G>>Ничего не мешает в рамках монолитного решения вынести отдельный инстанс для обработки тяжелых запросов и на уровне балансера распределять.
·>Видимо ты тут намекаешь на какую-то принципиальную разницу между SOA и MSA?

«Они очень маленькие. Даже сто строк кода, вероятно, считаются сегодня большим сервисом», — Фред Джордж, Barcelona Ruby Conference


«Команда на две пиццы» https://aws.amazon.com/executive-insights/content/amazon-two-pizza-team/


«Если сервис проектирует и поддерживает несколько программистов, то это не микросервис», — Фред Джордж, GOTO 2016


«Каждый сервис автономен, самостоятелен и выполняет уникальный процесс». https://www.paloaltonetworks.co.uk/cyberpedia/what-are-microservices#:~:text=Each%20service%20is%20autonomous%20and%20self%2Dcontained%20and%20runs%20a%20unique%20process


«Каждый микросервис упакован как контейнер Docker, чтобы обеспечить возможность развёртывания в кластер Kubernetes для оркестрации приложения». https://thinkmicroservices.com/


Тут и паттерны, и технологии, и оргструктуры и много чего еще.


·>Ещё почему-то ты предполагаешь что есть некий один универсальный балансер. А в приложухе может быть REST для аналитики, FIX для заказов и т.п.

Я не понял к чему эта фраза

G>>Еще раз повторю тезис: MSA это больше про оргструктуру и следующие за ней технические решения.

·>По-моему, ты причину со следствием путаешь.
А может и наоборот, не задумывался об этом?
Я вижу что микросервисы цветут там, где слишком много команд и разработчиков чтобы пилить монолиты. Поэтому техническая архитектура диктуется оргструктурой. Если у тебя команда небольшая или ты вообще один что-то делаешь — тебе в принципе не нужны микросервисы.


G>>А все инструменты: докеры, кубернетесы, балансеры, кэши, готовые сервисы хранения и расчетов, вполне можно применять даже если у вас весь ваш код в одной репе, копилируется в один бинарник и запускается в одном контейнере.

·>А зачем обязательно один бинарник? Если деплоймент разный всё равно. Чтобы были многочасовые билды?
А ты думаешь сборка одного толстого бинарника медленнее, чем сборка трех бинарников потоньше? Или ты думаешь что обязательно пересобирать все проекты каждый раз?
Да и в целом время сборки для деплоя мало интересует, интересует время от команды run до запуска приложения, если ты это делаешь 25 раз в день.

·>Сборка, деплой и перезапуск мелкого сервиса занимает минуты от момента мержа PR. Тогда как типичная выкатка монолита — приятно проведённые выходные.

В теории да. Но внезапно:
1) в микросервисах надо тупо больше кода править
2) если ты затрагиваешь несколько сервисов своим изменением, то несколько сервисов собираются дольше чем один
3) даже докер умеет кэшировать образы, поэтому вполне можно сделать сбору с кэшированием и не пересобирать то, что не изменилось
Re[11]: Помогите правильно спроектировать микросервисное приложение
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.04.25 22:01
Оценка:
Здравствуйте, Sinclair, Вы писали:

G>>А давай прикинем как это будет в MSA. там будет точно такая же коллекция в одном из сервисов, и менять её будет не поток, порожденный программистом, а поток порожденный хостом для обработки запроса. А все остальное будет то же самое. И, как в случае монолитного приложения, так и в случае MSA падения как такового не будет. Восстановление после такого falure возможно только сбросом состояния путем насильного перезапуска, например по хелсчеку. Разница в случае MSA будет только в том, что будет перезапущен один маленький сервис, а не толстое приложение. Но при этом весь сценарий работать не будет, пока микросервис с разделяемой коллекцией в памяти не оживет.

S>Всё верно. MSA не гарантирует безошибочности. MSA гарантирует, что падение не затронет сценарии, в которых микросервис не задействован.
Смотря что значит "не затронет". Если сервис А зависит от срвиса Б, а сервис Б содержит ошибку, даже неважно приводящую к падению или нет, то и А не будет корректно работать.
Падение — не самая страшная часть, даже в проде. Плохо когда: после падения не может подняться, или вместо падения не работает корректно — висит в ожидании или отдает некорректные данные. Причем второе при несинхронной разработке весьма вероятно.

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

S>Либо отказываться от разделяемого состояния. Потому что людей, умеющих изготовить полноценное клиент-серверное приложение внутри ACID-хранилища, на рынке не осталось (даже если предположить, что они когда-то были)
Его же не надо "внутри", надо чтобы разделяемое состояние польностью сохранялось и обрабатывалось ACID хранилищем, желательно внешним по отношению к самому приложению. Чтобы приложение можно было безопасно масштабировать и перезапускать.

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

S>Вопрос открытый. Чего я только не видел в энтерпрайзе, при самых грамотных архитекторах.
Бывает конечно всякое, и архитекторы, которые не понимают как и почему базы работают. Но в целом это подход по умолчанию: "давайте состояние приложения положим в базу". Раньше по умолчанию выбирали РСУБД, но сейчас уговаривать приходится.

G>>Опять-таки MSA ничем не помогает в этом случае. Без разницы будет мусор писать в базу микросервис или монолит.

S>Нет, разница принципиальная. Микросервис физически не может записать в чужую базу кривую запись о переводе денег.
Ну физически то может. Но сделать это гораздо сложнее чем в монолите.
Но у этой медали есть и обратная сторона: если у вас разные базы, то сделать джоин в них крайне сложно. Задачи которые в монолите бы решались одной строкой в SQL в MSA начинают требовать тонны кода.
Пример реальный: профили пользователей лежат в одном сервисе, данные о туристических маршрутах в другом. Важная часть логики: для несовреннолетних доступна одна часть маршрутов, для соврешеннолетных — другая. Есть еще другие признаки для фильтров: по регионам, интересам итд.
Теперь нам надо сделать рассылку, подобрав подходящие маршруты для клиентов.
В монолите — один джоин. В MSA — пожалуйста напишите тонну кода.
В реальности ситуация была еще хуже. Данные о бронях групп и совершенных путешествиях лежали в третьем сервисе. И конечно же надо было из предложений исключить тех кто уже ездил.


G>>Так это самые важные вопрос. Я еще раз напомню тезис, который в этой теме и другие коллеги подтверждают: MSA это больше про оргструктуру, а не про архитектуру. В интернетах предлагают "правильную" MSA с разделением микросервисов по разным репозитариям исходного кода. Как в этом случае обеспечить синхронность изменений разных микросервисах, если изменяемый бизнес-процесс затрагивает несколько таких микросервисов?

S>Никак — MSA, собственно, и обеспечивает отсутствие синхронности. Это преимущество, а не недостаток.
А в чем собственно преимущество? Ну если в деньгах посчитать.

S>Изменения в бизнес-процессе накатываются постепенно: сначала мы обучаем новостям самый "нижний" микросервис в топологически отсортированном списке микросервисов, затем — чуть более "верхние".

S>Изменения в БП становятся видны в тот момент, когда мы выкатываем изменения "корневого" микросервиса, который оркестрирует весь БП.
Если сервисы имеют строгую иерархию и представляют из себя "слои" приложения, то возможно это и так.
Но сразу три замечания:
1) это цикл внедрения фичи удлиняет. Так как скорости выгоднее делать "вертикальное" деление проекта.
2) Это противоречит мысли самодостаточности сервиса. "Верхний" не работает без "нижних", а "нижние" не нужны без "верних".
3) При падении\ошибке в "нижних" "верхние" тоже ломаются.



S>>>Но с таким подходом мы налетим на те же проблемы и в монолите — если мы ограничимся юнит-тестами компонентов без интеграционного тестирования получится ровно такой же результат.

G>>В msa весьма вероятна ситуация, что в принципе невозможно собрать работающее сочетание микросервисов. Я такое на практике видел. Было три микросервиса (А,Б,В) и два процесса(1,2), затрагивающие три сервиса. В один момент было так, что: А/HEAD, Б/HEAD, В/HEAD~1 работал сценарий 1, но не работал 2. А/HEAD, Б/HEAD~1, В/HEAD работал 2, но не работал 1 и при этом же А/HEAD~1, Б/HEAD, В/HEAD также работал 2, но не работал 1.

G>>И каждый разработчик миросервиса доказывал что "work on my microservice" (современный аналог work on my machine)

S>Это организационная проблема. В монолите все эти команды делали бы ровно то же самое ровно с тем же результатом.
Это в монорепе гораздо сложнее, до уровня "почти невозможно", так как версия всех компонент в монорепе всегда одна. Если вы не балуетесь выносом бизнес-логики во внешние пакеты.

S>А, ну и, возможно, неудачно были проведены границы между микросервисами. Это — отдельное искусство, настолько редкое, что я, ЕМНИП, видел только одно правильное решение (и с десяток заведомо неверных).

Может быть мне так везло, но я участвовал в 6 проектах с MSA и у десятка "стоял рядом" и везде были такие проблемы.
Более того я два проекта с MSA запилил назад в монолит и стало всем лучше. Но там четко одна команда работала над проектом.

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

S>Может быть. Я не говорю, что MSA — единственный верный способ деятельности
Я делаю более сильное утверждение: MSA пригодна только там, где есть соответствующая оргструктура: много несвязанных команд, каждая из которых работает на процессами, слабо связанными друг с другом. Такое в банках и маркетплейсах такое очень часто встречается, а они составляют основу русского бигтеха.
А например в корпоративных системах оно не надо, как при кастомной разработке, так и при разработке тиражируемого продукта.

G>>Доункаст к чему, если у него нет паблик класса, к которому даункастить?

S>Почему вы думаете, что нету?
S>А если нету — всегда можно запилить reflection. Пытливому уму все средства хороши.
Ну я точно также могу сказать про запись в чужую базу. Оно ведь все равно деплоится все в одно приложение докера\кубера и контейнеры видят друг друга. И все равно разраб сталкивается с тестовой средой, где может "в дикой природе" наблюдать какие еще сервисы работают и с какими хранилищами.

G>>Тут даже комментировать не буду. В дотнете и жабе полно средств изоляции. При желании даже в JS можно инкапсуляцию сделать, чтобы до потрохов никто не добрался.

S>Как раз в JS-то можно. Но, опять же, можно!=делают.
Так и в MSA изоляция зачастую условная. Да, у каждого сервиса база своя, но сервер БД один. Дорого поднимать несколько экзепляров даже постгреса. И учетные данные одни.
Если разработчикам не прививать дисциплину, то никакая изоляция не поможет.

G>>Так можно и в базу другого микросервиса полезть.

S>Невозможно. Базу чужого микросервиса даже не видно. И даже если вдруг чужая база лежит на той же машине, то доступ к ней выдан другому сервис-аккаунту, чем тот, под которым бегает этот микросервис.
Ну-ну. Это на практике может быть в бигтехе, где базы нарезаются отдельной командой и не входят в профиль деплоя. Но пока все приложение это одни набор yaml файлов для docker\kuber — пролезть можно. Опять-таки если недостаточная дисциплина.

Один раз премии лишить за рефлекшн без необходимости и сразу желание пропадет так писать.

G>>В случае единой репы и нормального архитектора — на ревью бить по рукам (или по лицу) за такой код.

S>Это всё хорошо работает до определённых размеров кодовой базы, команды, и уровня ответственности за промахи. Там, где за ошибки принято тюремное заключение или суровые штрафы, делают именно так, не полагаясь на бдительность peer review и личность архитектора.
Ну давай честно: есть предел размера команды или предел структуры управления для монолита. С этим никто не спорит.
Далее возможно развитие или по пути MSA или по пути "ядро\платформа и прикладная часть".
Но до этого предела монолит превосходит MSA по любым параметрам.

G>>Я именно об этом и говорю. Знаю один банк где над таким ядром-"микросервисом" трудится команда из 40+ только программистов. То есть ни разу он не "микро", о чем я и говорю. А выдача кредитов это вообще с десяток связанных процессов, на каждом из которых команда в 10+ человек. То есть их тоже "микро" назвать сложно.

S>Так "micro" это же не про размер команды. А про "площадь поверхности".
Не очень понятно в чем она измеряется.
Re[2]: Помогите правильно спроектировать микросервисное приложение
От: busk  
Дата: 03.04.25 09:07
Оценка:
Здравствуйте, Sinclair, Вы писали:


S>Важно, чтобы микросервисы как можно меньше взаимодействовали между собой. Если не получается — значит, границы выбраны неверно.

S>По вашему описанию не вполне понятно, что собственно должна делать система. Распределять заказы между водителями?
S>Смотрите:
S>0. Сервис аутентификации. Его хочется делать крайне надёжной, т.к. если никто не может зайти, то не работает вообще всё. Очень опасно делать монолит, в котором выкат какой-нибудь мелкой фичи типа "а давайте поздравим всех водителей-женщин с 8 марта" способен сломать логин. То есть эту штуку мы как можно реже релизим, и при каждом выкате покрываем тестами в шесть слоёв. Отдельные пацаны аудируют код на предмет потенциальных уязвимостей, т.к. кража базы паролей — почти самое плохое, что с нами вообще может случиться. Сам сервис скорее всего раскатан в нескольких экземплярах с геодистрибуцией и офигенной избыточностью — чтобы отключение света в нижегородском ДЦ не валило всю федеральную сеть водителей.
S>(Кстати, очень часто мы захотим это вообще делегировать наружу, чтобы не заниматься дорогостоящими инвестициями в эти пять девяток и прочие особенности. Привинчиваем OAuth и полагаемся на Google/Facebook/etc)
S>1. Сервис авторизации. После того, как пользователь залогинился, нам нужно ещё и получить набор его прав. В большинстве случаев это довольно-таки типовая структура, вроде ролей. Опять же, требования к ней довольно-таки жёсткие, т.к. она нужна в каждом первом сценарии. Ещё можно заметить, что она в значительной мере дублирует информацию из 0-й системы — как минимум, у нас должен быть тот же самый список пользователей. Поэтому в современном мире зачастую 0 и 1 объединяют в одну.



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

а вопрос такой: если это будет винда и один сервер то как проще организовать архитектуру двух сервисов (аутенфикация + авторизация) и всего остального?
докер или один общий шлюз (я так понял приложение) и дальше запрос идет либо на сервис 1 либо на сервис 2?
Re[14]: Помогите правильно спроектировать микросервисное при
От: · Великобритания  
Дата: 03.04.25 10:41
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>·>Гы. Как минимум, память и gc — разделяемые. Так что когда запрос какого-нибудь отчёта для аналитики вдруг роняет по OOM всё сразу, в т.ч. обработку заказов — ничего хорошего.

G>>>Ничего не мешает в рамках монолитного решения вынести отдельный инстанс для обработки тяжелых запросов и на уровне балансера распределять.
G>·>Видимо ты тут намекаешь на какую-то принципиальную разницу между SOA и MSA?
...
G>Тут и паттерны, и технологии, и оргструктуры и много чего еще.
Ок, можно согласится что в разных контекстах/организациях под SOA/MSA понимаются разные вещи. Нет никакого официального математически строгого определения.
Я рассуждаю с т.з. "собираем много разных бинарей, деплоим в разные места с разными опциями".

G>>>Еще раз повторю тезис: MSA это больше про оргструктуру и следующие за ней технические решения.

G>·>По-моему, ты причину со следствием путаешь.
G>А может и наоборот, не задумывался об этом?
Задумывался. Вполне возможно где-то может быть и наоборот в соответствии с карго-культом.

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

Иногда нужны — если есть соответствующие технические требования.

G>·>А зачем обязательно один бинарник? Если деплоймент разный всё равно. Чтобы были многочасовые билды?

G>А ты думаешь сборка одного толстого бинарника медленнее, чем сборка трех бинарников потоньше? Или ты думаешь что обязательно пересобирать все проекты каждый раз?
Гы. Трёх? Ты тут выше написал о сотне строк на сервис. За "монолит" объёмом на 3 сотни — я всеми конечностями.

G>Да и в целом время сборки для деплоя мало интересует, интересует время от команды run до запуска приложения, если ты это делаешь 25 раз в день.

В мире soa/msa часто бывает так, что запустить приложение ты просто не можешь командой run. Ресурсов на рабочей машине не хватит. Так что run запускаются только некоторые части, чаще просто тесты.

G>·>Сборка, деплой и перезапуск мелкого сервиса занимает минуты от момента мержа PR. Тогда как типичная выкатка монолита — приятно проведённые выходные.

G>В теории да. Но внезапно:
G>1) в микросервисах надо тупо больше кода править
зато общий impact правок ниже.

G>2) если ты затрагиваешь несколько сервисов своим изменением, то несколько сервисов собираются дольше чем один

В msa у тебя будет не три бинарника, а хотя бы тридцать. И работая над очередной фичей типично трогаешь 1-2, в плохих случаях 4-5 бинарников. А вот сборка 2 бинарников от 30 отличается уже на порядок.

G>3) даже докер умеет кэшировать образы, поэтому вполне можно сделать сбору с кэшированием и не пересобирать то, что не изменилось

А дальше? Как потом бинарник будет решать кем он сейчас работает — rest-сервером или fix-коннектором или распределённым кешем? Потребуется нетривиальная система конфигов.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 03.04.2025 11:02 · . Предыдущая версия .
Re[15]: Помогите правильно спроектировать микросервисное при
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 03.04.25 13:04
Оценка:
Здравствуйте, ·, Вы писали:

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

·>Иногда нужны — если есть соответствующие технические требования.
Предположим:
Команда из 10 человек, 7 разрабы, 3 аналитики и тестеры. Используется всеми один стек: условно дотнет и TS\react на клиенте.
Какие могут быть технические требования, чтобы с микросервисами они реализовывались проще, чем без них?


G>>·>А зачем обязательно один бинарник? Если деплоймент разный всё равно. Чтобы были многочасовые билды?

G>>А ты думаешь сборка одного толстого бинарника медленнее, чем сборка трех бинарников потоньше? Или ты думаешь что обязательно пересобирать все проекты каждый раз?
·>Гы. Трёх? Ты тут выше написал о сотне строк на сервис. За "монолит" объёмом на 3 сотни — я всеми конечностями.
уже на трех одновременно пересобираемых микросервисах время сборки монолита оказывается меньше.

G>>Да и в целом время сборки для деплоя мало интересует, интересует время от команды run до запуска приложения, если ты это делаешь 25 раз в день.

·>В мире soa/msa часто бывает так, что запустить приложение ты просто не можешь командой run. Ресурсов на рабочей машине не хватит. Так что run запускаются только некоторые части, чаще просто тесты.
Довольно странное заявление. Почему может не хватить ресурсов запустить проекта, который ничего не делает? Только кривостью рук разработчиков может быть такое решение обосновано.

G>>·>Сборка, деплой и перезапуск мелкого сервиса занимает минуты от момента мержа PR. Тогда как типичная выкатка монолита — приятно проведённые выходные.

G>>В теории да. Но внезапно:
G>>1) в микросервисах надо тупо больше кода править
·>зато общий impact правок ниже.
Я не понимаю что это. Что значит "общий импакт"? Я считаю количество строк\методов\объектов.

G>>2) если ты затрагиваешь несколько сервисов своим изменением, то несколько сервисов собираются дольше чем один

·>В msa у тебя будет не три бинарника, а хотя бы тридцать. И работая над очередной фичей типично трогаешь 1-2, в плохих случаях 4-5 бинарников. А вот сборка 2 бинарников от 30 отличается уже на порядок.
Тогда непонятно с чем ты споришь. Всегда найдется N, такое, что пересборка N микросервисов будет дольше чем пересборка монолита с аналогичным функционалом. Причем это N оказывается довольно небольшим. По моей практике N бывает от 3 до 5.

G>>3) даже докер умеет кэшировать образы, поэтому вполне можно сделать сбору с кэшированием и не пересобирать то, что не изменилось

·>А дальше? Как потом бинарник будет решать кем он сейчас работает — rest-сервером или fix-коннектором или распределённым кешем? Потребуется нетривиальная система конфигов.
Она все равно O(1), то пишется один раз и потом вносятся правки, независимые от объема изменений кода.
А кот конфиг для микросервисов зачастую O(N), так как развитие систем на базе MSA приводит к росту числа микросервисов, что в свою очередь увеличивает объем конфигов.
Re[3]: Помогите правильно спроектировать микросервисное приложение
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.04.25 13:56
Оценка: 3 (1)
Здравствуйте, busk, Вы писали:

B>а вопрос такой: если это будет винда и один сервер то как проще организовать архитектуру двух сервисов (аутенфикация + авторизация) и всего остального?

B>докер или один общий шлюз (я так понял приложение) и дальше запрос идет либо на сервис 1 либо на сервис 2?
Обычно никаких шлюзов нет, и пользователь явно идёт за токеном в сервис номер 1, а уже потом с этим токеном идёт в сервис номер 2.

Можем посмотреть на пример:

Сервис номер 2 расположен по адресу https://graph.microsoft.com/{version}/{resource}?{query-parameters}.
Токены для него получаем из сервиса номер 1 по адресу https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize

Наличие в сервисе 1 авторизации означает, что у вас сервис номер один возвращает в токене не просто идентити пользователя, а и некий набор привилегий, которые сервис номер 2 считывает для принятия решения о том, чего пользователю делать можно, а чего — нельзя. В частности, для Microsoft Graph мы прямо в запросе авторизационного токена сервису логина указываем список scopes, к которым хотим получить доступ. И в случае успеха, токен будет содержать информацию об этом.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: Помогите правильно спроектировать микросервисное приложение
От: Sharov Россия  
Дата: 03.04.25 15:39
Оценка:
Здравствуйте, ·, Вы писали:

·>И да, сервисы не через REST взаимодйествуют, а через pub-sub сообщения (kafka/29west/mq/fix/аналоги).


А в чем проблема взаимодействовать по REST'у?
Кодом людям нужно помогать!
Re[8]: Помогите правильно спроектировать микросервисное приложение
От: · Великобритания  
Дата: 03.04.25 20:49
Оценка:
Здравствуйте, Sharov, Вы писали:

S>·>И да, сервисы не через REST взаимодйествуют, а через pub-sub сообщения (kafka/29west/mq/fix/аналоги).

S>А в чем проблема взаимодействовать по REST'у?
Отсутствие гибкости. Rest — это синхронный p2p request-response только. Притом с большим оверхедом в виде http обёртки.
Сообщения — это кто угодно с кем угодно, streaming, множество отправителей/получателей и т.п. В MSA без такого трудно обойтись.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[16]: Помогите правильно спроектировать микросервисное при
От: · Великобритания  
Дата: 03.04.25 21:02
Оценка:
Здравствуйте, gandjustas, Вы писали:

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

G>·>Иногда нужны — если есть соответствующие технические требования.
G>Предположим:
G>Команда из 10 человек, 7 разрабы, 3 аналитики и тестеры. Используется всеми один стек: условно дотнет и TS\react на клиенте.
G>Какие могут быть технические требования, чтобы с микросервисами они реализовывались проще, чем без них?
Ну тут Sinclair вроде рассказывал варианты. Могу рассказать что я видал, но там много чего, а не просто ts/react. Сразу скажу, это торговые системы, где процент веба около нуля.

G>>>А ты думаешь сборка одного толстого бинарника медленнее, чем сборка трех бинарников потоньше? Или ты думаешь что обязательно пересобирать все проекты каждый раз?

G>·>Гы. Трёх? Ты тут выше написал о сотне строк на сервис. За "монолит" объёмом на 3 сотни — я всеми конечностями.
G>уже на трех одновременно пересобираемых микросервисах время сборки монолита оказывается меньше.
Очень сомневаюсь, когда бинарников десятки.

G>>>Да и в целом время сборки для деплоя мало интересует, интересует время от команды run до запуска приложения, если ты это делаешь 25 раз в день.

G>·>В мире soa/msa часто бывает так, что запустить приложение ты просто не можешь командой run. Ресурсов на рабочей машине не хватит. Так что run запускаются только некоторые части, чаще просто тесты.
G>Довольно странное заявление. Почему может не хватить ресурсов запустить проекта, который ничего не делает? Только кривостью рук разработчиков может быть такое решение обосновано.
А зачем вообще запускать что-то, что ничего не делает? Ты уж определись.

G>·>зато общий impact правок ниже.

G>Я не понимаю что это. Что значит "общий импакт"? Я считаю количество строк\методов\объектов.
Что обновив какой-нибудь условный коннектор с платёжной системой можно сломать только платежи, а не всю систему.

G>>>2) если ты затрагиваешь несколько сервисов своим изменением, то несколько сервисов собираются дольше чем один

G>·>В msa у тебя будет не три бинарника, а хотя бы тридцать. И работая над очередной фичей типично трогаешь 1-2, в плохих случаях 4-5 бинарников. А вот сборка 2 бинарников от 30 отличается уже на порядок.
G>Тогда непонятно с чем ты споришь. Всегда найдется N, такое, что пересборка N микросервисов будет дольше чем пересборка монолита с аналогичным функционалом. Причем это N оказывается довольно небольшим. По моей практике N бывает от 3 до 5.
Ну видимо какие-то простые маленькие системы в твоей практике были.

G>·>А дальше? Как потом бинарник будет решать кем он сейчас работает — rest-сервером или fix-коннектором или распределённым кешем? Потребуется нетривиальная система конфигов.

G>Она все равно O(1), то пишется один раз и потом вносятся правки, независимые от объема изменений кода.
G>А кот конфиг для микросервисов зачастую O(N), так как развитие систем на базе MSA приводит к росту числа микросервисов, что в свою очередь увеличивает объем конфигов.
Так растёт число не само по себе, а потому что добавляется новая функциональность, которую надо конфигурить — адреса-пароли-явки.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[9]: Помогите правильно спроектировать микросервисное приложение
От: Sharov Россия  
Дата: 03.04.25 22:33
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, Sharov, Вы писали:


S>>·>И да, сервисы не через REST взаимодйествуют, а через pub-sub сообщения (kafka/29west/mq/fix/аналоги).

S>>А в чем проблема взаимодействовать по REST'у?
·>Отсутствие гибкости. Rest — это синхронный p2p request-response только. Притом с большим оверхедом в виде http обёртки.
·>Сообщения — это кто угодно с кем угодно, streaming, множество отправителей/получателей и т.п. В MSA без такого трудно обойтись.

А что мешает его сделать асинхронным?
Кодом людям нужно помогать!