О, про зависимости при обмене через брокер весело. 1. У тебя для сценария с кафкой продюсер зависит от реализации консюмера, так как должен формировать ключ партиционирования в зависимости от требований консюмера. 2. Если ты хочешь что-то изменить на продюсере для одного консюмера, ты обязан убедиться, что все прочие консюмеры эту правку правильно отработают. Т.е. у тебя изменения одного консюмера зависит от всех прочих консюмеров, это очень жестко. Для http/grpc можно иметь несколько версий endpoint, а для брокеров это не пройдет ( 3. С брокером ты не можешь обновить "события в пути", т.е. тебе придется как-то реализовывать сложную логику, ээ, договора между всеми консюмерами и продюсером о смене версии события. Я знаю только один гарантированный сценарий для этого, но его никто не использует, так как слишком сложно )
Обычно обновить один сервис намного проще десятка сервисов
Не, без разницы. Всегда нужно думать про миграцию данных, фичафлаги, совместимость и так далее. И когда вокруг этого сделан тулинг - то обновление делается тривиально. А если нельзя договориться с соседними командами - то это проблема культуры и она не решается техническими средствами и будет проблемой вообще всегда. Впрочем, в твоем сценарии "прокси к данным" она будет сказываться вообще постоянно, так как любое изменение логики реконсиляции потребует (с большими шансами) изменение этого "прокси-сервера". А это происходит гораздо чаще, чем, ээ, переход с одной СУБД на другую. И, кстати, нет никакой проблемы выкатывать весь указанный функционал кусочками, с чего бы что-то не получилось?
О, я понял, где у тебя иллюзии. Нет, в современных БД в IO уже довольно сложно уткнутся, проблема обычно в ядрах и в оперативке. И тут гораздо дешевле сделать выборку прямо из БД и потом сделать массовый update, нежели прокинуть десятки миллионов записей через какой-нибудь микросервис. На сериализацию-десериализацию уходит очень, очень много ресурсов, поэтому любые массовые выборки стоит делать из своей БД, а не через микросервис. Попробуй протащить через сеть protobuf на 10 млн. записей (даже кусочками по 10k) и замерь, сколько у тебя уйдет ядер на это развлечение. Увы. но все современные протоколы обмена микросервисов не очень быстрые и с кучей дополнительных проблем (но почему gRPC почти всегда плохой выбор - отдельная тема). Ну и в конкретно этом случае у тебя еще и логика "сервиса доступа к базе" будет зависеть от всех сценариев реконсиляции, что увеличит зависимость.
И это не какой-то уникальный случай, это как раз нормальный кейс, который возникает всегда при работе со сколь-нибудь большими объемами данных и пристойной нагрузкой.
Смотря как делать. Если сделать общий Redis для всего проекта - так и получится, но так делать не нужно, у каждого микросервиса Redis должен быть свой собственный.
Почему должен? Если Redis используем для взаимодействия (pub-sub, общие блокировки и т.п.), то как раз нужен общий Redis. А если это локальный кэш, то зачем Redis?
контрактами и версионированием формата передаваемых сообщений
А ты пробовал это делать корректно? Там сразу вылезает взаимозависимость всех консюмеров по деплою и версионированию, это не лучше любой интеграции через view, только еще и миграцию хранимых данные сделать нельзя, что сильно все усложняет. То, что ты описываешь - обеспечивает потерю порядка и невозможность отката, так делать не надо ) На БД обеспечить совместимость гораздо проще, чем на очередях )
Хм, а какой один сервис ты написал бы что для первой задачи, что для второй? Да, в первой задаче нужно пропускать несколько миллионов записей за десятки минут на относительно дешевом железе. Во второй - общее число дочерних сервисов для отчетности - десятки с БД до терабайта. Да, при изменении схемы совместимым образом - нет проблем. При добавлении шардирования - вообще с реконсиляцией будет все нетривиально, проблемы работы с БД там будут вторичными (да, я знаю, пробовал). Замена одной СУБД на другую - всегда дорогая операция, для аналитических запросов - всегда требует их переписывать. Просто потому что все СУБД очень разные и с разными особенностями реализации. Кейсы, которые делаем на PG - нельзя сделать на CH и наоборот. А вот обновление пяти-десяти сервисов - это весьма тривиальная задача, кстати. Что там сложного-то? Точно проще, чем с помощью PG научить CH притворяться Вертикой )
Хм, например задача "реконсиляции" при обработке платежей. У тебя есть история эквайринговых транзакций банка (т.е. прошедших через банк транзакций магазинов, интернет-сайтов и так далее). И есть представление об этой истории у контрагентов (тех же магазинов, платежных систем и так далее). Раз в сутки нужно сверить твои представления о реальности с пришедшими от контрагентов файлами. Форматов файлов много, процессы сверки тоже заметно отличаются. По факту сверки нужно пометить транзакцию как "проверенную". Одно из решений - каждый тип сверки делается отдельным сервисом, но при этом все эти сервисы смотрят в одну общую базу "истории транзакций". Сами транзакции пишутся процессингом, а вот сервисы реконсиляции умеют только читать из конкретной вьюшки и изменять одно поле. Получается удобная интеграция через базу, с очень понятным и легко контролируемым контрактом (в том числе и через гранты). Прочие решения будут на порядок менее удобные.
Второй популярный кейс - аналитическая база. Куда пишут (через разные варианты ETL) куча разных сервисов и читают оттуда данные тоже куча разных сервисов для отдачи в bff или для долгосрочного хранения или для отчетности. Собственно, в МСА без этого вообще UI нормальный не сделать, не будешь же джойны и сложные фильтры делать ручками на bff?
А с распределенными базами типа YDB интеграция через базу вообще становится еще и масштабируемой по производительности. Ну и, если честно, kafka, redis или hazelcast - это тоже все про интеграцию через общее хранилище (общую базу). А используются все эти паттерны для обмена между сервисами очень широко.
"Изложите свой вариант, хотя бы тезисно?" Вариант чего? Проблемы взаимодействий в MSA? У меня минимум три доклада разных на эту тему - и это все равно про весьма поверхностный подход к теме.
Хм, а где там усиление связи? Какая разница, контракт описывает entrypoint или view или вообще strored procedure - это все описание контрактов. И версионирование для view сделать не сложнее, чем для http calls (и, в среднем, проще, чем для gRPC).
И чтение - это совсем не мелочь, подход с кэшированием данных в своей базе (то, что ты называешь подпиской) - очень сложный, очень трудоемкий (при обеспечении минимальных гарантий), очень сильно повышающий связность, почти никак не версионируемый и, в большинстве случаев, вообще антипаттерн.
Общие транзакции для разных сервисах, разумеется, не реализуемы. Но и подобных потребностей при "интеграции через БД" несколько меньше, так как не нужно инвалидировать кучу кэшей в других сервисах, достаточно поменять данные только в одном месте.
Автор статьи, подозреваю, вообще никогда не видел ни MSA, ни монолита. Так как при наличии хоть какого-то опыта в статье было бы хоть что-то содержательное )
MSA это, в первую очередь, про упрощение арх.контроля и, реже, про возможность работать с разными НФТ для разных частей продукта (скорее про безопасность и надежность, чем про масштабируемость). Других плюсов там особо и нет. Но какой-нибудь ArchUnit вполне решает задачу контроля.
Вообще, при современных распределенных БД не совсем понятно, в чем проблема в общей БД для множества сервисов. Контракт интеграции, особенно для чтения, легко реализуется через view и, при этом, будет много эффективнее, чем тот же gRPC.
Впрочем, в статье столько всякой чуши написано, что нет смысла даже критиковать. Как будто плохую книжку по сисдизайну пересказывают, еще и десятилетней давности...
По DDD лучше всего читать собственно Эванса (первую книжку). Ну и Хорикова (но там больше статьи). Но книжки по DDD не помогут нарезать домены, тут лучше что-нибудь базовое по теории систем (хоть вузовский учебник, хоть Акоффа).
Какие еще языки для корпоративной разработки вы пробовали? В каких у вас есть серьезные компетенции? Без разнообразного опыта сложно говорить про "хороший" или "плохой" язык. А вот те, у кого есть достаточно разнообразный опыт - обычно относятся к Python с большим сомнением, тем более при использовании динамической типизации.
По МСА совсем уж хороших книг как не было, так и нет. Есть база типа Клеппмана, есть неплохие идеи в разных книжках у Ньюмана и Ричардса, но любые советы и рекомендации нужно читать осторожно и сверять с реальностями вашего проекта и потенциальными проблемами. Часто рекомендации не очень соответствуют реальности. Кстати, вместо Building Microservices лучше бы почитать Software Architecture: The Hard Parts тех же авторов.
А вот про выбор подхода - нет каких-то четких условий. В среднем, если домены хорошо нарезаны, то необходимости ходить в чужую БД вообще нет. Но иногда все-таки нужные чужие данные и тут Shared DB надежнее (не нужна синхронизация, реконсиляция и так далее), но хуже масштабируемо и требует аккуратного арх.контроля. Если команда не слишком опытная, инфраструктура хорошая и много денег - то можно смело идти в Databse-per-service. В реальности, конечно же, приходится думать над конкретным проектом и выбирать подходящее решение.
Так у AI вообще плохо с арифметикой. А статью, судя по всему, сгенерила LLMка (и вряд ли это был платный ChatGPT, скорее что-то бесплатное и поднятое на ноутбуке, судя по результату). Судя по всему, в МТС примерно так и относятся к своим разработчикам, не видя разницы между тимлидами и устаревшими LLMками.
Ну, студенты вряд ли лучше пишут, чем профессионалы (причем в конкретном языке). Но я про то, что дизайн исследования изначально такой, что даже за курсовую не засчитать, не говоря уж за публикацию.
О, про зависимости при обмене через брокер весело.
1. У тебя для сценария с кафкой продюсер зависит от реализации консюмера, так как должен формировать ключ партиционирования в зависимости от требований консюмера.
2. Если ты хочешь что-то изменить на продюсере для одного консюмера, ты обязан убедиться, что все прочие консюмеры эту правку правильно отработают. Т.е. у тебя изменения одного консюмера зависит от всех прочих консюмеров, это очень жестко. Для http/grpc можно иметь несколько версий endpoint, а для брокеров это не пройдет (
3. С брокером ты не можешь обновить "события в пути", т.е. тебе придется как-то реализовывать сложную логику, ээ, договора между всеми консюмерами и продюсером о смене версии события. Я знаю только один гарантированный сценарий для этого, но его никто не использует, так как слишком сложно )
Обычно обновить один сервис намного проще десятка сервисов
Не, без разницы. Всегда нужно думать про миграцию данных, фичафлаги, совместимость и так далее. И когда вокруг этого сделан тулинг - то обновление делается тривиально. А если нельзя договориться с соседними командами - то это проблема культуры и она не решается техническими средствами и будет проблемой вообще всегда. Впрочем, в твоем сценарии "прокси к данным" она будет сказываться вообще постоянно, так как любое изменение логики реконсиляции потребует (с большими шансами) изменение этого "прокси-сервера". А это происходит гораздо чаще, чем, ээ, переход с одной СУБД на другую.
И, кстати, нет никакой проблемы выкатывать весь указанный функционал кусочками, с чего бы что-то не получилось?
О, я понял, где у тебя иллюзии. Нет, в современных БД в IO уже довольно сложно уткнутся, проблема обычно в ядрах и в оперативке. И тут гораздо дешевле сделать выборку прямо из БД и потом сделать массовый update, нежели прокинуть десятки миллионов записей через какой-нибудь микросервис. На сериализацию-десериализацию уходит очень, очень много ресурсов, поэтому любые массовые выборки стоит делать из своей БД, а не через микросервис. Попробуй протащить через сеть protobuf на 10 млн. записей (даже кусочками по 10k) и замерь, сколько у тебя уйдет ядер на это развлечение. Увы. но все современные протоколы обмена микросервисов не очень быстрые и с кучей дополнительных проблем (но почему gRPC почти всегда плохой выбор - отдельная тема).
Ну и в конкретно этом случае у тебя еще и логика "сервиса доступа к базе" будет зависеть от всех сценариев реконсиляции, что увеличит зависимость.
И это не какой-то уникальный случай, это как раз нормальный кейс, который возникает всегда при работе со сколь-нибудь большими объемами данных и пристойной нагрузкой.
Смотря как делать. Если сделать общий Redis для всего проекта - так и получится, но так делать не нужно, у каждого микросервиса Redis должен быть свой собственный.
Почему должен? Если Redis используем для взаимодействия (pub-sub, общие блокировки и т.п.), то как раз нужен общий Redis. А если это локальный кэш, то зачем Redis?
контрактами и версионированием формата передаваемых сообщений
А ты пробовал это делать корректно? Там сразу вылезает взаимозависимость всех консюмеров по деплою и версионированию, это не лучше любой интеграции через view, только еще и миграцию хранимых данные сделать нельзя, что сильно все усложняет.
То, что ты описываешь - обеспечивает потерю порядка и невозможность отката, так делать не надо )
На БД обеспечить совместимость гораздо проще, чем на очередях )
Хм, а какой один сервис ты написал бы что для первой задачи, что для второй? Да, в первой задаче нужно пропускать несколько миллионов записей за десятки минут на относительно дешевом железе. Во второй - общее число дочерних сервисов для отчетности - десятки с БД до терабайта.
Да, при изменении схемы совместимым образом - нет проблем. При добавлении шардирования - вообще с реконсиляцией будет все нетривиально, проблемы работы с БД там будут вторичными (да, я знаю, пробовал). Замена одной СУБД на другую - всегда дорогая операция, для аналитических запросов - всегда требует их переписывать. Просто потому что все СУБД очень разные и с разными особенностями реализации. Кейсы, которые делаем на PG - нельзя сделать на CH и наоборот.
А вот обновление пяти-десяти сервисов - это весьма тривиальная задача, кстати. Что там сложного-то? Точно проще, чем с помощью PG научить CH притворяться Вертикой )
Хм, например задача "реконсиляции" при обработке платежей. У тебя есть история эквайринговых транзакций банка (т.е. прошедших через банк транзакций магазинов, интернет-сайтов и так далее). И есть представление об этой истории у контрагентов (тех же магазинов, платежных систем и так далее). Раз в сутки нужно сверить твои представления о реальности с пришедшими от контрагентов файлами. Форматов файлов много, процессы сверки тоже заметно отличаются. По факту сверки нужно пометить транзакцию как "проверенную".
Одно из решений - каждый тип сверки делается отдельным сервисом, но при этом все эти сервисы смотрят в одну общую базу "истории транзакций". Сами транзакции пишутся процессингом, а вот сервисы реконсиляции умеют только читать из конкретной вьюшки и изменять одно поле.
Получается удобная интеграция через базу, с очень понятным и легко контролируемым контрактом (в том числе и через гранты). Прочие решения будут на порядок менее удобные.
Второй популярный кейс - аналитическая база. Куда пишут (через разные варианты ETL) куча разных сервисов и читают оттуда данные тоже куча разных сервисов для отдачи в bff или для долгосрочного хранения или для отчетности. Собственно, в МСА без этого вообще UI нормальный не сделать, не будешь же джойны и сложные фильтры делать ручками на bff?
А с распределенными базами типа YDB интеграция через базу вообще становится еще и масштабируемой по производительности.
Ну и, если честно, kafka, redis или hazelcast - это тоже все про интеграцию через общее хранилище (общую базу). А используются все эти паттерны для обмена между сервисами очень широко.
"Изложите свой вариант, хотя бы тезисно?"
Вариант чего? Проблемы взаимодействий в MSA? У меня минимум три доклада разных на эту тему - и это все равно про весьма поверхностный подход к теме.
Хм, а где там усиление связи? Какая разница, контракт описывает entrypoint или view или вообще strored procedure - это все описание контрактов. И версионирование для view сделать не сложнее, чем для http calls (и, в среднем, проще, чем для gRPC).
И чтение - это совсем не мелочь, подход с кэшированием данных в своей базе (то, что ты называешь подпиской) - очень сложный, очень трудоемкий (при обеспечении минимальных гарантий), очень сильно повышающий связность, почти никак не версионируемый и, в большинстве случаев, вообще антипаттерн.
Общие транзакции для разных сервисах, разумеется, не реализуемы. Но и подобных потребностей при "интеграции через БД" несколько меньше, так как не нужно инвалидировать кучу кэшей в других сервисах, достаточно поменять данные только в одном месте.
Автор статьи, подозреваю, вообще никогда не видел ни MSA, ни монолита. Так как при наличии хоть какого-то опыта в статье было бы хоть что-то содержательное )
MSA это, в первую очередь, про упрощение арх.контроля и, реже, про возможность работать с разными НФТ для разных частей продукта (скорее про безопасность и надежность, чем про масштабируемость). Других плюсов там особо и нет. Но какой-нибудь ArchUnit вполне решает задачу контроля.
Вообще, при современных распределенных БД не совсем понятно, в чем проблема в общей БД для множества сервисов. Контракт интеграции, особенно для чтения, легко реализуется через view и, при этом, будет много эффективнее, чем тот же gRPC.
Впрочем, в статье столько всякой чуши написано, что нет смысла даже критиковать. Как будто плохую книжку по сисдизайну пересказывают, еще и десятилетней давности...
По DDD лучше всего читать собственно Эванса (первую книжку). Ну и Хорикова (но там больше статьи).
Но книжки по DDD не помогут нарезать домены, тут лучше что-нибудь базовое по теории систем (хоть вузовский учебник, хоть Акоффа).
Какие еще языки для корпоративной разработки вы пробовали? В каких у вас есть серьезные компетенции?
Без разнообразного опыта сложно говорить про "хороший" или "плохой" язык. А вот те, у кого есть достаточно разнообразный опыт - обычно относятся к Python с большим сомнением, тем более при использовании динамической типизации.
А у автора есть реальный опыт проектирования и защиты сайзинга для сколь-нибудь сложных систем? А то тут что не пункт - то ошибка проектирования (
Хм, из этих статей можно сделать только один выводы - их автор не умеет читать и не умеет в бенчмарки. Что-то еще есть?
И откуда такой вывод? И качество библиотек при этом учитывалось или в расчет принимались любые работы джунов?
По МСА совсем уж хороших книг как не было, так и нет. Есть база типа Клеппмана, есть неплохие идеи в разных книжках у Ньюмана и Ричардса, но любые советы и рекомендации нужно читать осторожно и сверять с реальностями вашего проекта и потенциальными проблемами. Часто рекомендации не очень соответствуют реальности. Кстати, вместо Building Microservices лучше бы почитать Software Architecture: The Hard Parts тех же авторов.
А вот про выбор подхода - нет каких-то четких условий. В среднем, если домены хорошо нарезаны, то необходимости ходить в чужую БД вообще нет. Но иногда все-таки нужные чужие данные и тут Shared DB надежнее (не нужна синхронизация, реконсиляция и так далее), но хуже масштабируемо и требует аккуратного арх.контроля. Если команда не слишком опытная, инфраструктура хорошая и много денег - то можно смело идти в Databse-per-service.
В реальности, конечно же, приходится думать над конкретным проектом и выбирать подходящее решение.
Для высоконагруженных - Rust, Java,
Go - скорее для очень простых и не слишком нагруженных микросервисов.
Ну или для средненагруженных системных утилит, тут он вообще идеален (так как для этого и проектировался).
Так у AI вообще плохо с арифметикой. А статью, судя по всему, сгенерила LLMка (и вряд ли это был платный ChatGPT, скорее что-то бесплатное и поднятое на ноутбуке, судя по результату).
Судя по всему, в МТС примерно так и относятся к своим разработчикам, не видя разницы между тимлидами и устаревшими LLMками.
Ну, студенты вряд ли лучше пишут, чем профессионалы (причем в конкретном языке).
Но я про то, что дизайн исследования изначально такой, что даже за курсовую не засчитать, не говоря уж за публикацию.