Pull to refresh

Comments 25

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

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

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

Если что-то в получившейся системе, состоящей в основном из связей, не устраивает, то переделывают конкретный кусок, минимизируя область поражения, а не всё целиком - там тысячи человеко-лет закопаны, это просто невозможно без остановки развития.

  • Никто не понимает, как это всё совместно работает

  • Есть куча кода, про который толком не понять что реально именно он делает, и что сломается если его "немного переписать"

  • Выбросить всё целиком уже нельзя, ибо вложено очень много и как-то, но работает.

  • Производительность и отзывчивость стала непредсказуемой, и кроме "добавить больше серверов" ничего принципиально не помогает. И то не всегда. Где-то есть узкое место. Но где - непонятно.

А не возврат ли это к проблеме легаси, за который жутко ругали монолиты, но уже на новом витке и с ещё худшими последствиями?

Никто не понимает, как это всё совместно работает

Прелесть в том, что это и не требуется.

Есть куча кода, про который толком не понять что реально именно он делает, и что сломается если его "немного переписать"

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

Производительность и отзывчивость стала непредсказуемой, и кроме "добавить больше серверов" ничего принципиально не помогает. И то не всегда. Где-то есть узкое место. Но где - непонятно.

Для решения проблем с производительностью применяются специальные инструменты для распределённого трейсинга и развитая система сбора метрик.

А не возврат ли это к проблеме легаси, за который жутко ругали монолиты, но уже на новом витке и с ещё худшими последствиями?

Монолиты чем плохи?
- Тяжёлый сервис кушает много железа
- В который много людей коммитит, значит постоянно есть конфликты
- Совокупная сложность очень большая
- Обычно у монолитов невысокая скорость релиза фич

А что микросервисы?
- Много маленьких кусочков кушают в сумме +- столько же ресурсов, скорее больше, чем меньше
- Коммиттеры распределены по кусочкам
- Совокупная сложность выше, но в каждом конкретном месте всегда меньше
- Скорость релизов очень высокая

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

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

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

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

PS У монолитов тоже есть плюсы, как ни странно. Меньше дурной и непредсказуемой асинхронности, например.

Таков путь, что тут ещё скажешь :)

Таков путь

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

Лучше так и делать конечно, лично я в работе стараюсь проводить линии раздела сервисов там, где это осмысленно с точки зрения data oriented подхода, но это далеко не всегда очевидно в момент принятия решения.

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

Можно конечно. И куча фирм так и делает. Только далеко не везде это работает. Например потому что если медленно пилишь новые фичи, то в отдельных нишах тебя обходят конкуренты которые делают это быстро.

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

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

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

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

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

В целом опять как всегда - не инструмент виноват, а пользователь.

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

Это опять возвращает нас к проблеме множества генералов на поле боя.

Если что-то в получившейся системе, состоящей в основном из связей, не устраивает, то переделывают конкретный кусок, минимизируя область поражения, а не всё целиком

Это применимо к любому варианту, проблема только в различии способов доставки изменений. Если доставку архитектурно сделать эффективной, то и монолит вполне позволит "минимизировать область поражения".

Если приложение монолитное, то перезапустить придётся всё приложение целиком. Это означает, что миллионы пользователей Твиттера начнут страдать.
Они перезапускают один мкросервис, при этом его работу никто не выполняет

Вовсе нет. Что микросервис, что монолит можно поднять в нескольких инстансах и переключать - green/blue deployment, довольно простая штука. В больших системах желательно каждый сервис делать с оглядкой на горизонтальное масштабирование - обычно это несложно, если изначально заложить.

Второе - все должны знать, что делать, если соседний ёжик не хочет работать.

Что внутри монолита выполнение функции может прерваться с выбросом исключения, что при обращении к сервису запрос может вернуть ошибку. Обрабатывать нужно в любом случае, просто по-разному. А чем больше проект и больше пользователей, тем чаще случаются даже крайне маловероятные ситуации.

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

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

Подняв тысячу микросервисов, мы сразу получим задачу на мониторинг этого зоопарка.

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

И, как мы видим, сотрудники Твиттера её решили просто - покупаем 100 000 серверов (не виртуальных), нанимаем 10 000 человек, и вуаля - у нас даже что-то работает.

Вы хорошо знаете, какие проблемы возникали и как решались в Твиттере, или просто "да я это сделаю за ночь и бутылку водки"?

В идеале, миллион независимых микро-сервисов легко переключится на другой адрес при падении одного из миллиона участников. [...] Но чаще всего получается как в Твиттере - 100 000 серверов и миллиарды в год на содержание бегемота.

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

Здесь люди идут по проторенной дорожке, что означает - действие по шаблону. Они смотрят, а что там у соседа. Если у соседа что-то работает и по меркам индустрии затраты приемлемые, то вывод здесь простой - я хочу так же.

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

Что микросервис, что монолит можно поднять в нескольких инстансах и переключать - green/blue deployment

Проблема не в инстансах, а в подключенных клиентах. В том же твиттере в каждый момент открыты тысячи сессий. Им всем придётся умереть.

Что внутри монолита выполнение функции может прерваться с выбросом исключения, что при обращении к сервису запрос может вернуть ошибку. Обрабатывать нужно в любом случае

Повторю из статьи - там разный алгоритм. В монолите некуда переключатьcя. А в микросервисе есть.

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

О ком знает микросервис - зависит от архитектора (о чём опять же было написано). А сама необходимость введения шины нам говорит лишь об одном - квадратичный рост является проблемой и один из способов борьбы - шина.

один раз создав и описав входящий/исходящий интерфейсы сервиса, это будет переиспользовано другими сервисами

Вносимая асинхронность с вами несогласна. Есть и другие специфические моменты.

Для монолита тоже мониторинг нужен по предметным областям и тут пофиг, это монолит или сервисы

Если вы имеете в виду внешние интерфейсы, то да, они мало меняются. Но зачем же забывать о создании тысячи внутренних?

А предметно-независимый, то бишь инфраструктурный мониторинг вообще-то шаблонный, его тоже достаточно один раз описать и переиспользовать

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

Вы хорошо знаете, какие проблемы возникали и как решались в Твиттере, или просто "да я это сделаю за ночь и бутылку водки"?

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

Пожалуйста, не экстраполируйте плохие практики на всю индустрию, если не знаете наверняка

Кое-что знаю. Но да, о Твиттере - только из интернета. Оттуда же про 100 000 серверов, и про десяток тысяч работников, ну и про остальное. Остальное как раз сильно намекает на то, что видел сам лично.

Проблема не в инстансах, а в подключенных клиентах. В том же твиттере в каждый момент открыты тысячи сессий. Им всем придётся умереть.

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

Повторю из статьи - там разный алгоритм. В монолите некуда переключатьcя. А в микросервисе есть.

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

О ком знает микросервис - зависит от архитектора (о чём опять же было написано). А сама необходимость введения шины нам говорит лишь об одном - квадратичный рост является проблемой и один из способов борьбы - шина.

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

  2. Общая шина данных используется не только в микросервисной архитектуре - во многих фреймворках реализован observer и я во многих проектах видел использование внутри монолита.

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

Вносимая асинхронность с вами несогласна. Есть и другие специфические моменты.

Какая асинхронность? Речь же была о реализации и документировании API. Один раз описываем и реализуем driving интерфейс при создании сервиса - какой-нибудь REST API для примера. Для сервисов, которые будут его использовать, потребуется клиент: либо действительно в каждом пишем свою копию, либо создаем общий и переиспользуем. Тут здорово могут помочь какие-нибудь protobuf/gRPC. Один раз описываешь структуры и получаешь и документацию, и болванку сервера, и клиенты под кучу языков. Никакого бойлерплейта. А составление исходного описания сопоставимо по затратам с описанием интерфейса какого-нибудь фасада в монолите. Ну и один раз накладные расходы на регистрацию нового API в балансировщике - копипаст нескольких строк + деплой.
Если же Вам принципиально не нравится, что тут появляются сетевые задержки, то да, это недостаток. Но тут я напомню, что микросервисы обычно появляются тогда, когда вертикальное масштабирование становится невозможным, поэтому возможности избежать сетевых запросов в этом вопросе попросту не существует. Микросервисы на микроскопических проектах без перспектив большого роста, надеюсь, тут не рассматриваем :)

Если вы имеете в виду внешние интерфейсы, то да, они мало меняются. Но зачем же забывать о создании тысячи внутренних?

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

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

Не об интерфейсах речь, я имел в виду два типа мониторинга: бизнес-метрики и технические. Бизнес-метрики в любом случае нужно реализовывать что в монолите, что в сервисах: нужно знать активность пользователей, отслеживать платежи, контролировать воронки активаций, проводить А/Б-тесты и т.д. Это не зависит от архитектуры проекта. А технические метрики типа доступности сервиса, кол-ва ошибок, дисконнектов, состояния железок и виртуалок и т.д. мало зависят от реализации софтины и обычно являются шаблонными: вот шаблон метрик по железке, вот по nginx/apache, вот по MySQL/PostgreSQL/noSQL. И тут особо нет разницы, условный HTTP API один на 1000 методов в монолите или их 10 по 100 методов для фронта плюс еще 100 по 10 методов для внутреннего взаимодействия. Даже не копипаста, а массовое применение один раз написанного шаблона.

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

Т.к. тут вы выходили за рамки подтверждаемых утверждений - туше.

Видится мне так: клиенты ж не напрямую к сервисам подключаются, а через балансировщики, так что клиентская сессия останется живой

Ну вот, вы уже торгуетесь.

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

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

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

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

Общая шина данных используется не только в микросервисной архитектуре - во многих фреймворках реализован observer и я во многих проектах видел использование внутри монолита.

Вы опять не обратили внимания на причину использования шины.

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

Последствия более очевидны - нет или есть накладные расходы. Результат - вместо, скажем, 10 000 серверов твиттер имеет 100 000.

Какая асинхронность?

Пример - очереди.

Речь же была о реализации и документировании API

Про документирование вы не говорили, а про реализацию - она стала асинхронной.

Если же Вам принципиально не нравится, что тут появляются сетевые задержки, то да, это недостаток

Там ещё в 10 раз больше серверов появляется.

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

Конечно, 10 против 100 тысяч.

нужно знать активность пользователей, отслеживать платежи, контролировать воронки активаций, проводить А/Б-тесты и т.д

Про это написано в разделе про аналитику.

доступности сервиса, кол-ва ошибок, дисконнектов, состояния железок и виртуалок и т.д. ... условный HTTP API один на 1000 методов в монолите

Монолит падает один раз. Микросервисы - 1000. Разница 1000 раз вам ничего не говорит? Условный HTTP API один только для монолита. А для микросервисов протокол один, а параметров - 1000 наборов. И обычно под мониторинг в каждом сервисе выделяют отдельный вход - вот ещё 1000 задачек.

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

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

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

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

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

UFO landed and left these words here

Вы пишите серьёзную статью, не не похоже, что она основана на полноценном опыте в каждом из направлений.

Для примера, типовой стек простого мониторинга (берём готовое ПО): prometheus, node_exporter, victoriametrics (3 микросервиса), grafana, БД grafana (распределённая, 3 микросервиса), prometheus alert manager, любая система реагирования на инциденты (1-2 микросервиса), шиппер логов, хранилище логов (эластик [3 микросервиса], loki).

Примерно 15 микросервисов в самом простом варианте и это я наверняка что-то забыл.

Это не "готовое ПО", это готовое решение. В других решениях цифры могут быть другими.

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

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

Современные сети ботов выявляются на основе кучи факторов таких как связанности пользователей внутри сети, на основе уникальности контента, на основе отношения к ним доказанно живых пользователей. Знаете, что у этих показателей общего? Они требуют анализа больших объемов информации. Уже на обслуживании одной инфраструктуры вам потребуется немало людей. А ещё куча специалистов, которые пишут алгоритмы для вычленения информации из текста, изображений и видео.

Да, в такой работе есть сложная часть, и я на неё указывал, правда без подробностей.

В плане "куча специалистов" - да, какое-то количество потребуется, но это один отдел, вместе со всеми нейросетями и прочим для рекламы. Одни и те же люди. Одно и то же железо. Железо мощное, но не запредельно (не тысячи серверов).

Разумеется, если ставить цель тренировать какую-нибудь GPT-4, тогда вам потребуется домик метров сто длинной для одних только серверов, но я сильно сомневаюсь в необходимости такой задачи в случае с твиттером.

Просто - внесли изменение в часть приложения

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

Если приложение монолитное, то перезапустить придётся всё приложение целиком. Это означает, что миллионы пользователей Твиттера начнут страдать.Они перезапускают один мкросервис, при этом его работу никто не выполняет

Эта задача решена уже миллион лет назад, с появлением первых 24/7 систем, решается одинаково, что для монолита, что для микросервисов, разница лишь в том, что при изменениях в структуре баз данных, с монолитом геморроя больше, как и шансов на ошибку, ибо данные у них как правило реляционные.

Решается очень просто - одновременно работают и старая и новая версии, новые сессии открываются на новых версиях серверов, старые работают до тех пор пока не будут завершены все старые сессии.

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

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

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

С раздутым монолитом над которым работают сотни разработчиков это нифига не просто.

Я не говорил, что абсолютно всё следует держать в одном монолите. Этого никогда не требовалось, например в мире Java. Там уже больше 20 лет существует концепция сервера приложений, где условный единственный монолит организации давно разделён на отдельные приложения. Результат - два-три десятка приложений слабо зависимы. Но работают все на одном сервере. Сам сервер, разумеется, даёт нам кластеризацию и прочие способы масштабирования, но приложения об этом не задумываются (ну почти). Всё это - на основе опыта с приложением в организации с десятками миллионов клиентов.

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

одновременно работают и старая и новая версии, новые сессии открываются на новых версиях серверов, старые работают до тех пор пока не будут завершены все старые сессии

Правильно, но вы уже разбили монолит. Это означает, что претензии у вас не ко мне, а к вашему собственному пониманию.

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

Каждый класс "знает" о других. То есть при необходимости может и взаимодействовать. Лёгкость организации взаимодействия ведёт к повышению количества связей. Хотя да, можно не учитывать мои слова из текста о сильной зависимости количества связей от умений архитектора.

Идеал микросервисной архитектуры это когда сервисы настолько не связанны, что вообще друг с другом никак не разговаривают и дел не имеют

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

Соответственно, организация, работавшая с серверами приложений, переходит на микросервисы уж точно не из-за того, о чём говорите вы.

Это то, с чем я столкнулся лично, что на предыдущем месте работы, что на текущем. И это только одна из проблем, толкающая на распиливание прекрасного монолита, которым еще несколько лет назад люди гордились. Монолиты имеют тенденцию расти.

Правильно, но вы уже разбили монолит. Это означает, что претензии у вас не ко мне, а к вашему собственному пониманию.

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

Каждый класс "знает" о других. То есть при необходимости может и взаимодействовать.

Ага, однако у конструкторов (или через что там ваш DI работает) ваших классов бизнес-логики от силы с десяток параметров, очень редко когда больше, вот и вся связность монолитов. Которую, тем не менее, с помощью микросервисов предлагаются уменьшать. Так что ни о какой квадратичной зависимости речи не идет.

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

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

Нет, не разбил. Разные сервера это разные инстансы одного и того-же сервиса

Разбили, но не заметили. Кодовое слово - балансер.

Ага, однако у конструкторов (или через что там ваш DI работает) ваших классов бизнес-логики от силы с десяток параметров, очень редко когда больше, вот и вся связность монолитов

Компоненты приложения взаимодействуют через вызов методов, а не конструкторов. Методов может быть тысяча (гуглим god's class)

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

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

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

Разбили, но не заметили. Кодовое слово - балансер.

А у вас значит балансеров нет, всегда один инстанс? Просто интересно. Впрочем, даже если и так, по вашей логике вы свой монолит все равно разбили, как минимум, на веб-сервер и сам монолит.

Компоненты приложения взаимодействуют через вызов методов, а не конструкторов.

Чтобы вызвать чей-то метод нужен инстанс класса. А инициализацией инстансов и добавлением их в инстансы классов бизнес логики занимается dependency injection. Через конструктор, или через поля, это уже дело десятое, однако именно этим набором инстансов можно оценить количество связей объектов бизнес-логики. И даже у монолитов не будет квадратичных прямых зависимостей.

Квадратичность достижима легко, ну а неверие в силу "настоящих художников" 

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

Sign up to leave a comment.

Articles