Comments 111
Хм, как раз недавно был вопрос по поводу микросервисов.
Если кодовая база самого микросервиса относительно небольшая и он делает одну, но сложную задачу, а сам docker-образ вместе с зависимостями весит больше 5ГБ, это тоже будет микросервис?
P.S. NodeJS? :))
Микро определяется областью ответственности а не размером. Вполне нормальный микросервис.
завтра еще какую-нибудь фигню придумают.
Уже придумали. Это Blockchain
Ну в общем-то в итоге большие ребята так и сидят на виртуальных серверах в облаках, и потихоньку дробятся на микросервисы, которые распихиваются по контейнерам. И это нормальный абсолютно подход к проектированию сейчас.
Мы можем переписать 1 сервис на другой язык, ну к примеру на java и протестировать как это будет работать. мы даже можем протестировать это на процентном соотношение, например «Сервис комментарий у нас на python, мы переписали его на java и пустили трафик 70/30» и померили что быстрей…
Такое невозможно сделать с монолитом.
Если есть Core — значит на нем завязаны все (ну или большинство), он центр зависимостей. А такого не должно быть в рамках микросервисов, распределенная же система, децентрализованная. Это примерно как god object.
А как сервисам между собой общаться? :)
Часто это сервер очередей или сервис, которы знает, как в кого ходить.
Если же они будут безобразно ходить друг в дружку, то это только увеличение бардака, с которым мы якобы пытались бороться :)
В общем, в неумелых руках любая технология будет порождать проблемы. :)
Часто это сервер очередей или сервис, которы знает, как в кого ходить.
вы сейчас описываете штуки вроде enterprise service bus и это тип устаревшая модель.
Обычно сервисы ходят друг в друга по сети, неиболее популярный вариант — старый добрый http. Многие используют штуки аля zeromq. То есть нет единого "сервиса" который знает как кто куда общается, ибо это сервис завязал бы всех на себе и являлся бы узким местом.
Если же они будут безобразно ходить друг в дружку, то это только увеличение бардака, с которым мы якобы пытались бороться :)
Именно друг в дружку. Если по аналогии, посмотрите картинку. В ней кружочки одинакого цвета представляют составные части микросервисов (у нас их на картинке 3) а жирные стрелочки между ними — это как они ходят по сети.
В целом микросервис должен быть самодостаточен настолько, что бы посадить на каждый отдельную команду разработчиков.
В общем, в неумелых руках любая технология будет порождать проблемы. :)
Согласен полностью. Микросервисы это последний тренд к сожалению. Модно это.
То есть нет единого «сервиса» который знает как кто куда общаетсяА если сервис на который завязаны другие, сменит ip/dns, ходить и вручную менять конфиги, или как?
это сервис завязал бы всех на себе и являлся бы узким местом.Сделать несколько нод с репликацией, чтобы не быть узким местом.
А если сервис на который завязаны другие, сменит ip/dns, ходить и вручную менять конфиги, или как?
ну так… в чем проблема? Не надо завязываться на то что может резко поменяться и все) Ну а так да, можно сервис дискавери замутить.
Сделать несколько нод с репликацией, чтобы не быть узким местом.
можно конечно, но всеравно по итогу все завязаны на один способ общения. А так можно эксперементировать. Где-то простой http, где-то zeromq с бинарными протоколами, где-то еще что-то.
Какая связь между DDD и применением разных ЯП в одном проекте?
Насколько я понимаю, если кусочек проекта может быть скомпилирован или задеплоен независимо от основного проекта, то это уже микросервис.
Продолжу кидать ссылки на видосики: Eric Evans — DDD & Microservices: At Last, Some Boundaries!. Тут хорошо раскрыта связь между DDD и микросервисами.
p.s. вы как бы и правы и нет. Ну то есть если вы проектируете монолит, вы можете париться о bounded context-ах но с микросервисами это выходит явно потому что… ну если этого не делать то все будет… плохо. Явные границы лучше неявных.
С другой стороны если разработчик не понимает как правильно сделать монолит — в микросервисах ему точно делать нечего. Микросервисы как бы… дают профит в плане масштабируемости. И если у вас база данных влезет на один сервер или команда не настолько большая что тесно, то наверное не стоит лезть в это болото.
а) Появляется представление о том, когда микросервисы не нужны, а когда будут вполне себе неплохим решением
б)+ к скилу проектирования(в т.ч монолитных приложений)
в) Практический опыт ДО реальной необходимости
Спасибо за видео!
Иначе это напоминает перебор индекса массива (больше/меньше, строгое/нестрогое неравенство), чтобы программа заработала. :)
Понимания 0.
Мало у кого есть личные проекты (хотя это плюс, а то имеем сапожников без сапог), а тем более требующие микросервисов.
>Практический опыт ДО реальной необходимости
Это типа умение дрочить? :)
В реальности это все разобъется в пух и прах.
В реальности придется думать в каждом конкретном случае, как резать монолит.
Фреймворки за вас это не сделают.
Кмк, вещи нужно использовать по мере необходимости и с пониманием.
У меня тоже был дурной опыт. Например, с ООП. Молодой неокрепший ум (+без опыта коммерческой разработки еще) начитался, что это круто: наследование тебе, инкапсуляция.
Ну и начал натягивать ООП (так был сделан, слава богу, только один подраздел).
На поверхности был как бы ООП. Но это был ад. Я код вообще перестал понимать. :)
Плюнул потом и переписал так, как понимаю.
То есть:
Не нужно пытаться что-то использовать, потому что так все делают. Та плевать, как кто делает.
Не нужно свой код подстраивать под что-то, не понимая этого чего-то.
А также, наверное, не стоит советовать новичкам идти по пути непонимания и наименьшего сопротивления.
Нужно меньше догм.
Но это не значит, что не нужно интересоваться новыми подходами. Нужно. Только применять их с пониманием.
Нужно заранее понимать, нужен ли сервис в данной ситуации или нет.
Нет. В целях обучения мы можем выделять эти сервисы искуственно. Нет ничего дурного в том, что бы в собственных проектах пробовать разные подходы и получать практический опыт их применения.
Мало у кого есть личные проекты (хотя это плюс, а то имеем сапожников без сапог)
Разработчик без личных проектов — тоже самое, что адвокат без судебной практики. Это как
разработчик без аккаунта guthub и знания английского. Право на существование само собой имеет, но это уж точно не то к чему стоит стремиться.
В реальности это все разобъется в пух и прах.
У меня например не разбилось, что я делаю не так?
В реальности придется думать в каждом конкретном случае, как резать монолит.
Очевидно, однако, если ты пользуешься одними и теми же архитектурными принципами, то этот процесс будет, как минимум унифицирован. Вот был у меня DDD проект. Взял, да повыдергивал домены на микросервисы. Часа 2 заняло с учетом написания Dockerfile.
Фреймворки за вас это не сделают
Проектирование это и не задача фреймворков.
Это типа умение дрочить? :)
Это не умение дрочить, это подкрепление теоретической базы практикой, что является стандартным в процессе обучения практически любому навыку.
Первый раз мы решаем квадратное уравнение до реальной необходимости это сделать(у многих такая необходимость не возникает вообще никогда).
Кмк, вещи нужно использовать по мере необходимости и с пониманием.
Да, в таком случае при возникновения этой самой необходимости ты делаешь миллионы ошибок, которые такой же программист УЖЕ преодалел, изучая и практикуясь.
На поверхности был как бы ООП. Но это был ад. Я код вообще перестал понимать. :)
Ну я до первого опыта коммерческой разработки использовал ООП и даже все эти абстрактные фабрики, стратегии и прочие синглтоны. Может всетаки дело не в необходимости а отсутствии у кого-то системного подхода к собственному обучению?
Не нужно пытаться что-то использовать, потому что так все делают
Нужно хотя бы понимать, что они делают и почему они это делают. А еще лучше уметь это делать тоже. Тогда у тебя будет хотя бы шанс оценить, нужно ли оно тебе или нет. А иначе получается поведение 14-летнего подростка в духе: «ФУ, микросервисы мейнстрим, лучше буду дерьмо жрать с кучей инстансов монолитных приложений, зато НИКАК ФСЕ»
Та плевать, как кто делает
Ну это вообще какой-то вброс дерьма на вентилятор. Стандарты? Паттерны? Лучшие практики? Что объединят три предыдущих вопроса? Это именно то «как делают другие» и разработчику на это не должно быть плевать.
Не нужно свой код подстраивать под что-то, не понимая этого чего-то
Обратного никто не утверждал.
А также, наверное, не стоит советовать новичкам идти по пути непонимания и наименьшего сопротивления.
Этого им тоже никто не советовал, ну, во всяком случае, я точно не советовал.
Нужно меньше догм
Назовите хоть одну — уберем.
Но это не значит, что не нужно интересоваться новыми подходами. Нужно. Только применять их с пониманием.
Для того, что бы у тебя появилось понимание, тебе нужно сначала их как минимум использовать :)
Повторю еще раз начало своего сообщения:
В это болото можно и нужно лезть и из собственного интереса, но не на деньги работодателя
Обучение без необходимости — это дерьмо. Человек ни хрена не поймет.
Знания получил, думать не научился. :)
Прежде всего нужно учить думать.
>Разработчик без личных проектов — тоже самое, что адвокат без судебной практики.
Совсем не то. И это сплошь и рядом.
>У меня например не разбилось, что я делаю не так?
Может это Вам лишь так кажется? :)
>Проектирование это и не задача фреймворков.
Уже нет? Не они задают архитектуру? :)
>Первый раз мы решаем квадратное уравнение до реальной необходимости это сделать
Сравнение некорректное.
Решая квадратное уравнение мы решаем конкретную задачу: найти x.
Здесь же абстрактное обучение в вакууме.
Еще раз:
Есть потребность — делаем, нету — не делаем.
Не нужно искусственно что-то натягивать.
>Да, в таком случае при возникновения этой самой необходимости ты делаешь миллионы ошибок, которые такой же программист УЖЕ преодалел, изучая и практикуясь.
Программист, пишущий на фреймворках? :)
Та они (в основном) и шагу ступить без него не могут.
Я не спорю, что нужна практика. Но эта практика не должна быть надуманной и без понимания. Тогда это не практика. А сферический вакуум.
>Может всетаки дело не в необходимости а отсутствии у кого-то системного подхода к собственному обучению?
1. Я не считаю себя супер-программистом.
2. Необходимости в ООП не было, а я поддался моде. (Ну как вы советуете сейчас идти пилить микросервисы :) )
Если Вы применяли с пониманием (хотя Вы говорите, что без :) ) и оно было необходимо (хотя в случае с микросервисами Вы говорите, что нет), то ок :)
>ФУ, микросервисы мейнстрим, лучше буду дерьмо жрать с кучей инстансов монолитных приложений, зато НИКАК ФСЕ.
Я такого не говорил.
Я всегда говорю: Все нужно использовать по потребности и с умом! А не искать серебрянные пули.
>Назовите хоть одну — уберем.
Вы сами их упомянули:
«Стандарты? Паттерны? Лучшие практики?»
А также: ООП — тру (в последнее время: ФП — тру), фреймворки — тру, goto — зло.
Ну не везде это нужно и оправдано. Тем более без понимания.
>Обратного никто не утверждал.
Как же. Вы же советуете играть с микросервисами без необходимости в них (а значит понимания нету).
>Ну это вообще какой-то вброс дерьма на вентилятор. Стандарты? Паттерны? Лучшие практики? Что объединят три предыдущих вопроса? Это именно то «как делают другие» и разработчику на это не должно быть плевать.
Разработчик, который не умеет думать, а использует готовую догматику, не понимает, что он делает.
На поверхности получаем якобы и стандарты, и паттерны, и практики, только оно такое говнокодное, что капец. Ну или несвязная копипаста из разных мест :)
Это обезьяна, а не разработчик.
Серебрянной пули нету, а вы всем ее суете.
>Для того, что бы у тебя появилось понимание, тебе нужно сначала их как минимум использовать :)
Нет.
Нужно читать стоящие книжки, смотреть примеры, делиться опытом.
Иначе это будет варение в себе.
На поверхности будут вроде и микросервисы, только сторонний наблюдатель подумает: ну нахера это тут?
Если человек применяет подход без понимания, то он обезьяна.
>В это болото можно и нужно лезть и из собственного интереса, но не на деньги работодателя
Я согласен, что заниматься экспериментами на деньги работодателя не стоит.
Я против этого и выступаю, когда крутые перцы говорят: а не переписать ли все на A фреймворк, а не поменять ли нам БД, а не добавить сюда еще эту приблуду.
Хотя необходимости в этом нет, просто им скучно.
Если же есть необходимость, то вряд ли ваш личный проект будет больше требовать разбиения на микросервисы (а они нужны не такому и большому количеству сайтов).
Если же есть необходимость, то вряд ли ваш личный проект будет больше требовать разбиения на микросервисы
Мой личный проект в среднем обрабатывает 10к запросов в секунду, думаю, на этом можно закончить :D
2. Не нужно ничего доказывать. Я не стараюсь что-то доказать. Я стараюсь найти аргументацию, что для чего в каких случаях больше подходит, в каких случаях А может быть лучше Б, в каких нет.
В данном случае — в каких случаях и как стоит использовать микросервисы.
3. Если я в чем-то ошибаюсь, приводите аргументы. Но не детский лепет, который разбивается в пух и прах. (Это не только вам адресовано). Если укажете на ошибку, я будут только благодарен.
>Мой личный проект в среднем обрабатывает 10к запросов в секунду, думаю, на этом можно закончить :D
Ну это совсем другой разговор. :)
Мало какие коммерческие имеют такие показатели (а подавляющее большинство и не имеет). Вы могли двигаться в сторону микросервисов, большинство же нет. :)
Но нужно смотреть, что скрывается за этими запросами. :)
Тут https://habrahabr.ru/post/262623/ тоже крутые цифры, а под капотом работа с первичным ключом одной таблицы.
Не надо экстраполировать свою самоуверенность на все отрасли человеческой деятельности.
Не надо экстраполировать свою самоуверенность на все отрасли человеческой деятельности.
Золотые слова. Возможно для вас они тоже должны прозвучать. Просто поверьте что в мире есть люди которые знают что делают.
2. Люди, которые знают, что делают, конечно же есть. Я этого тоже не отрицал :)
Но не все то золото, что блестит:
Например.
То, что проект большой, не значит, что он умно сделан (тем более во всем). :)
Посмотрите для примера на богомерзкую мордокнигу.
И режут на микросервисы не только из-за масштабируемости, а и:
а) чтобы не было блокировок, когда вместо синхронного выполнения тяжелой операции выполняютт ее в фоне.
б) когда был монолит, но мы захотели предоставлять API доступ к нему: мобильное приложение, сторонние клиенты.
А вот базу сложнее масштабировать.
У кого-то есть данные, сколько занимают главные таблицы пользователей в ВК и ФБ? :)
Основная поболь, кмк, невозможность выполнить запрос над данными более одного сервера.
Хотя тут: https://habrastorage.org/getpro/habr/post_images/a07/038/4e5/a070384e516dd5466ee15fc314b1dc44.png
https://habrahabr.ru/company/oleg-bunin/blog/309330/
как бы есть решение.
А также есть малоизвестный mysql-движок FEDERATED.
Мне интересен такой вопрос:
Как будет работать шардинг с группировками по данным из нескольких шард? :)
Потому что обычные запросы можно выполнить и отдельно на каждом сервер.
Работают ли межсерверные джойны (хотя это ад)?
А также:
Стоит ли делать шардинг по UUID (когда большинство запросов именно по UUID) и кто как его делает.
Есть ли range ранжирование?
Хорошо спроектированный монолит раздробить несложно
Спасибо, кэп.
В комментарии, на который Вы в начале ветки ответили, обратного и не утверждалось )))
Это дорого, потому что сложно. Сложность следует из многгобразия.
Когда тут ява, тут пхп, тут Си а, тут дядька на баше накорябал так, что никто не разберет — получается зоопарк технологий. И на каждую технологию вам нужны: специалисты, обновления, лицензии, сервера и т.д. А дядька на баше уволился — и все ищи ветра в поле…
Плавали, знаем.
Идеально иметь одну серверню технологию и один скрипт язык.
ЯП (язык программирования) это инструмент, а инструмент нужно использовать по назначению.
Никто и не спорит, что язык надо подбирать под задачу. Это, можно сказать, уже стало мантрой среди программистов. И принцип этот, конечно же, правильный. Весь вопрос в том, что считать задачей. Чем она определяется? По сути, задача определяется, так называемым, условием задачи. Есть главное условие, собственно что нужно сделать, а есть уточняющие условия, накладывающие дополнительные ограничения, и добавляющие свою специфику. Так вот, наличие у компании уже готовой кодовой базы на каких-то языках, и специалистов, знакомых с определенными языками и технологиями, тоже является частью условия. И если какой-то язык или фреймворк более-менее подходит, и он уже используется в других проектах, то лучше не вводить новых сущностей. И тут нет никакого противоречия с принципом «инструмент под задачу». Мы как раз выбираем инструмент под нашу задачу. Не под какой-то архетип задачи, а под нашу конкретную задачу, учитывая все условия.
Что до крупных компаний, типа Google, то у них есть свои особенности, связанные с их размером. Наверное зоопарк технологий для них неизбежен. Но успеха они достигают вовсе не благодаря ему. Скорее уж вопреки. Ставка на архитектуру — это как раз инструмент борьбы с негативными эффектами от зоопарка.
И если какой-то язык или фреймворк более-менее подходит, и он уже используется в других проектах, то лучше не вводить новых сущностей.
А потом оказывается, что кодовая база монолита на устаревших языках/фреймворках (или их версиях) разрослась настолько, что только за поддержку нужно платить большие деньги, а переписать вообще практически не реально.
Ну или даже без устаревания, на этапе постановки начальной задачи фреймворк более-менее подходил, но с годами, по мере изменения задачи всё менее и менее, а переход на более подходящий становится всё дороже и дороже.
В общем, однозначного «лучше» точно не может быть. Влияет на лучше слишком многое, чтобы давать универсальные советы.
Старение не так страшно, когда можешь сам омолаживать по необходимости (самопись).
В случае умирания фреймворка/CMS, выхода новой несовместимой версии поимеем боль :)
Зоопарк сложнее поддерживать.
Сотрудники слабо взаимозаменяемы.
Выгоды от зоопарка больше у крупных компаний.
Да, в принципе, всё совпадает с моим опытом использования микросервисов. Вот только статья совершенно не раскрывает вопрос "зачем тогда вообще с этим связываться".
Мой ответ — повторное использование уже сделанной работы. Рассматривайте микросервисы как библиотеки 2.0 со следующими преимуществами:
- интегрировать микросервис проще, чем библиотеку. Никаких конфликтов, никаких зависимостей, никакой головной боли с конфигурированием. Есть сетевое API по известному протоколу.
- библиотека позволяет повторно использовать алгоритмы. Микросервис позволяет повторно использовать еще и данные без многих недостатков интеграционной СУБД (см. Фаулера Integration database antipattern)
- микросервисы, в отличие от библиотеки, позволяют скрыть свои зависимости от клиентов. Это позволяет писать как более гибкие, так и более устойчивые приложения. Например, микросервис отправки писем единственный хранит настройки email-сервера и может предпринимать дополнительные усилия по доставке писем.
- как обобщение предыдущего пункта, микросервисы изолируют проблемы конфигурирования кода. Те же адреса SMTP, баз данных, JMS… Большой монолит частенько имеет весьма обширную конфигурацию.
- гораздо богаче возможности по версионированию. Система может одновременно использовать несколько разных версий одного и того же микросервиса, если не все клиенты не готовы делать миграцию. Не разных версий API, а именно разных версий бинарника с несовместимыми API.
Про цену микросервисов хорошо написано выше. Да, нужно будет сильно вложиться в инфраструктуру. Да, проектирование интерфейсов микросервисов — это очень сложная и ответственная задача, так что лучше начать с монолита. Но я считаю, что в большинстве случаев оно того стоит.
Да, тот же Фаулер много про это пишет. Выделение микросервиса — это большая ответственность, т.к. нужно стремиться к тому, чтобы любая доработка системы затрагивала минимальное количество микросервисов. А это требует глубоких знаний системы, которые как правило появляются уже после её написания.
интегрировать микросервис проще, чем библиотеку
На мой взгляд — одинаково. Если библиотеке нужен был параметр конфирурации — то у микросервиса он никуда не денется, просто вы его сконфигурируете в другом месте.
микросервисы изолируют проблемы конфигурирования кода.
И кудаж они их девают по-вашему? На мой простой взгляд, если у монолитного приложения наружу торчит скажем один http-порт, то у микросервисов их потенциально будет по числу самих сервисов. И где тут уменьшение проблем конфигурирования?
гораздо богаче возможности по версионированию.
И гораздо сложнее протестировать все возможные варианты и сочетания версий.
Я в целом к тому, что даже если все эти преимущества вдруг реализуются в жизни (что бывает не всегда) — они все равно будут чего-то стоит. Т.е. это не бесплатно.
> И кудаж они их девают по-вашему?
sarcasm on
Да все просто — добавляем микросервис конфигурирования всей инфраструктуры.
sarcasm off
К сожалению в крупных проектах так и делают.
Конечно не бесплатно, просто нужно выбирать решения, которые дают больше плюсов, чем минусов :-) По пунктам, местами гиперболированно:
- пусть нам нужно отправлять письма. В случае библиотеки мы имеем конфигурацию e-mail сервера в 10 местах и много работы при смене e-mail провайдера, в случае микросервиса — конфигурация одна, код интеграции с email — один
- service discovery. В рамках системы должен быть единый механизм поиска сервиса по имени и авторизации. В этом плане есть различие между внутенними сервисами (микросервисы) и внешними сервисами(почта/база/JMS/...) Т.к. первые контролируются вами, что означает унифицированный интерфейс, обратную совместимость, отсутствие хитрых параметров конфигурации и необходимости мигрировать на альтернативные реализации.
- Тестирование — это отдельный большой разговор. Вкратце, моё мнение — микросервисы должны тестироваться изолированно на соответствие своему контракту API. Плюс какие-то базовые приемочные тесты всей системы. К сожалению, полные приемочные тесты часто становятся узким местом — из-за быстродействия, объема и ограниченного кол-ва людей, которые с ними работают.
Простите, но почему "монолит" — это вдруг сразу один класс или один метод? Там тоже как правило есть модули, и там тоже конфигурация e-mail сервера в одном месте а не в 10. Другие варианты возможны — но это не монолит, а клиника. Так нормальные люди уже не делали, когда и этого слова микросервис никто не знал.
Грубо говоря, я уже лет 10 назад вполне себе делал приложение из скажем пяти десятков EJB, каждый из которых занимался своим делом. У них был свой (внутренний, обычно) API, и они вполне себе повторно использовались. JavaEE контейнер, внутри которого сотни модулей — это микросервисы, или еще нет? :) А OSGI, где сотни бандлов, в том числе многие нескольких версий параллельно — это все еще оно?
Успешная попытка выделить то же самое как отдельный сервис означает как правило, что это просто очень типовой сервис, вроде упомянутого вами e-mail, который действительно всем нужен. За пределами приложения.
Но это автоматически означает одну простую вещь — если вы это вынесли наружу и опубликовали, вы становитесь поставщиком этого сервиса. Со всей вытекающей ответственностью. Захотели изменить что-то? Ан нет — нельзя, потребители не готовы. Выкатывайте другую версию, рядом, а эту продолжайте поддерживать. Тут могут быть и плюсы, и минусы — но они далеко не всегда так очевидны и примитивны, и далеко не все чисто технические.
Мне не пришлось поработать над большим (большой=нет ни одного человека, который знает детали функционирования всех модулей) монолитным проектом — будет интересно, если вы прокомментируете его недостатки, как я их вижу :-)
- прибитые гвоздями технологии. Старая джава, старые версии библиотек, которые достаточно сложно заменить на более новые.
- недостаточный уровень изоляции. Всё приложение работает на одном общем пуле ресурсов, и ошибка в одном модуле может уронить/испортить всё приложение
- Большое время старта приложения
- Большой объем конфигурации, сложное управление зависимостями между модулями
Основная идея микросервисов — это декомпозиция. То, что сервисом можно пользоваться, не изучая его исходники и зависимости.
И я совсем забыл про главное преимущество микросервисной архитектуры — устойчивость. Кластер из микросервисов может переживать аппаратные и программные сбои любого характера, более "мягко" реагирует на перегрузку, может терять функциональность частично, позволяет деплоймент без даунтайма, разнообразные разноцветные тестирования и т.п.
Старые технологии — это все имеет место, само собой. Например, есть у нас большой проект, сделанный на старых технологиях. Некоторые из них уже и на сайте разработчика найти проблематично — настолько устарели, документация либо удалена, либо в архиве. Смигрировать его на более новые — очень сложно. Хотя реально это OSGI с кучей модулей, которые вполне независимы друг от друга. И с библиотеками реально проблем мало. Сложно смигрировать инфраструктуру — т.е. например OSGI сам по себе, или допустим Spring/Camel etc.
Но с другой стороны — мне сложно представить, что бы было, если бы вместо контейнера (с общей инфраструктурой типа мониторинга и управления) была бы пара сотен микросервисов. Не вижу, почему бы объему работы снизиться.
Насчет уровня изоляции — ну это тоже не факт, что недостаток. Общим пулом ресурсов может быть проще управлять, чем скажем распределить память (которая все равно ограничена) между множеством независимых компонентов, когда вы не знаете, сколько конкретно каждому из них нужно.
Время старта? Ну да, был случай в практике, когда томкат стартовал на настольной машине минут 15 — занимаясь это время тем, что закачивал в память огромный кеш. Только это не время старта монолита — это время старта де-факто одного сервиса. Ну вот такой сервис, да. И потом, чтобы сократить время старта, вам нужно, чтобы микросервисы были реально независимы друг от друга. А то представьте — ядро стартовало, очень быстро, но половина функций недоступна, потому что старт части сервисов еще в процессе. Это само по себе может быть немаленькой проблемой.
Конфигурация? Ну опять же — я совершенно не вижу причин, почему ее должно стать меньше. Наоборот — если у меня условно "монолит", то в нем скажем есть JMX (и консоль типа hawtio), и вся конфигурация и управление — там. А если у меня сотня сервисов — то у меня сотня JMX, и управление сотней сервисов. Т.е. число точек конфигурирования и управления не имеет тенденции сокращаться, если мы не сокращаем функциональность. Скорее уж наоборот.
Ну и напоследок — возможно, для меня просто "монолит" это давно уже то, что правильнее называть "контейнер", т.е. JavaEE или OSGI. И он в жизни давно кластер, он деплоится на лету, и т.д и т.п. А настоящего своего монолита я много лет и не видел пожалуй.
Микросервисы можно мигрировать по одному, микросервисы можно вообще не трогать, пока они работают. И даже когда придет необходимость дописывать микросервис, одновременно релизить всех его клиентов необязательно — можно задеплоить и старую, и новую версию.
В плане утилизации ресурсов на каждый модуль/микросервис — это забота админа и нагрузочного тестирования. Да, это требует соответствующего мониторинга.
Современное приложение должно стартовать 2-3 секунды, не больше. Иначе теряется flow при разработке. Поддерживает ли osgi параллельный старт разных модулей?
Мониторинг и агрегация мониторинга — это отдельная работа, которая в случае микросервисов делается долго, но один раз. Изменения конфига налету через JMX — имхо, плохая идея, т.к. теряется воспроизводимость релиза. В случае редеплоя мы можем эти настройки и не применить и получим неожидаемое поведение. Что касается точек управления — микросервис должен быть задеплоен один раз и просто работать, не требуя каких-либо подкручиваний. При правильной декомпозиции, объем конфигов перед релизами должен уменьшаться.
Да, монолит как один здоровенный кусок лапши, индустрия, к счастью, уже оставила позади. Пожалуй, в настоящее время монолитом можно назвать EE/OSGI приложения, которые не рискуют деплоить отдельными модулями, а только целиком.
OSGI поддерживает все что угодно. Можно стартовать по очереди, можно остановить половину. Это именно что микросервисы в их самом явном виде. Но при этом это еще и контейнер.
Что до времени старта — то я не зря приводил пример. Есть приложения, которые стартуют минутами. Это их работа такая. И это вообще не показатель ничего.
Я подозреваю, что мы просто имеем дело с разными типами приложений. У меня вполне нормально, что приложения подкручиваются регулярно. На них влияет рынок, и его нужно учитывать — и хорошо бы не при помощи релизов.
Пожалуй, в настоящее время монолитом можно назвать EE/OSGI приложения, которые не рискуют деплоить отдельными модулями, а только целиком.
Ну, к сожалению, я такие знаю. IBM BPM — это такое вот JavaEE, которое состоит всего порядка из пяти EAR, и при этом не просто деплоится только целиком, а еще и предполагает, что мы кучу всего в контейнере (Websphere) понастроим, чтобы оно завелось.
Было бы не плохо еще и рассказать какой оверхед стоит за использованием микросервисов.
- Деплоймент новых версий
- Транзакции и ролбеки
- Агрегаторы
- Логирование ошибок
- Авторизация
- Общий код, который используют разные версии сервисов
- Обработка и вывод ошибок
- Разработка внутренних стандартов для request/response
Как-то однобоко получилось.
Есть монолит, есть сервисы, есть монолит+сервисы. И то, и то востребовано в разработке.
умение писать ленивый и некачественный код снижается
Вот это:
your ability to write lazy or poorly thought out code decreases
мне кажется, тоже не очень хорошо сформулировано, но хотя бы понятно, что хотел сказать автор — он имеет в виду, что уменьшается возможность писать плохой код. И «poorly thought out» — это не «некачественный», а «непродуманный», хотя бы.
Популярный подход — строить архитектуру таким образом, что логические «сервисы» владеют частями предметной области.
У нас примерно так и сделано. По сути, получаются сервисы из монолитов, связанные через REST и AMQP.
Плюсы подобного подхода несомненны: жесткое разделение баз данных, открытый API, которым могут пользоваться не только мы, более быстрые тесты. Раньше прогон всех тестов монолита занимал минут 30, теперь модули собираются параллельно.
Изолированность — это круто, на самом деле. Например, нам пришлось переписать часть модулей с Cassandra на MySql, и это прошло практически незаметно для остальных сервисов, т.к. REST API не поменялся.
Предвидя возражение вида «просто надо верхний уровень проектировать с первого раза правильно», сразу отвечу, что это очень часто зависит не от проектировщиков а от
Самый важный урок — API должен быть доступен через некий центральный роутер (у нас — haproxy), тогда даже дробление/слияние модулей слабо повлияет на видимый api.
А то заставь дурака богу молиться. :)
>Например, входящие API-запросы, фронтэнд панели управления и фоновые задачи могут находиться в одной кодовой базе, но не обязательно на каждой машине обрабатывать все три типа запросов.
На самом деле это микросервис :)
С таким успехом монолитом нельзя считать 2 системы, работающие на одном фреймворке. :)
А вообще какая разница что это: отмасштабированный монолит / чистейший микросервис.
Разве отмасштабированный монолит не может в придачу общаться посредством очереди кроме балансировки по урл?
Главное, чтобы задачи решало.
У кого-то микросервисы могут ходить в одну базу / писать/читать одни и те же файлы.
У кого-то все изолировано (как при использовании сторонних API).
если можно использовать ту же кодовую базу?
Специально для вас: Greg Young — Stop Over-Engenering
У кого-то микросервисы могут ходить в одну базу / писать/читать одни и те же файлы.
в этом случае микросервисы превращаются в распределенный монолит. У вас узкое место (одна база данных) так и остаются.
У вас узкое место (одна база данных) так и остаются.
Справедливости ради, база данных далеко не всегда является узким местом.
Мне влом смотреть 50 минут.
Вы хотите сказать, что я проповедник оверинжиниринга? :)
Вроде во всем спорах, в т.ч. с Вами, я выступаю против него. :)
>в этом случае микросервисы превращаются в распределенный монолит. У вас узкое место (одна база данных) так и остаются.
Плевать.
Нам что завести 2-100500 баз данных с пользователями для каждого микросервиса, который с ними работает?
Выйдет что-то на постном масле. :)
Блин, в прошлом моем комменте
«С таким успехом монолитом нельзя считать 2 системы, работающие на одном фреймворке. :)»
следует читать так:
«С таким успехом микросервисом нельзя считать 2 системы, работающие на одном фреймворке. :)»
Вы хотите сказать, что я проповедник оверинжиниринга? :)
Ну от части. И я тоже. Я думаю вам понравится, посмотрите)
Вроде во всем спорах, в т.ч. с Вами, я выступаю против него. :)
вот потому я ссылку и даю. Вопервых далеко не все ваши высказывания чушь) Во вторых — мы по разному трактуем оверинженеринг.
Нам что завести 2-100500 баз данных с пользователями для каждого микросервиса, который с ними работает?
нет. Будет одна база данных с пользователями и каждая база данных для себя будет хранить кусочек информации которая нужна ей. Денормализация и все такое.
И да, это сложно и для 99.9% проектов это не нужно. Но зато позволяет вам более гибко подходить к процессу разработки системы.
Микросервисы особенно хороши, если замешать все на каком-нибудь messaging в виде транспорта (для легкости broadcast/unicast обмена) и приправить auto discovery (для минимизации конфигурации зависимостей)
Банки любят такую архитектуру, т.к. она гарантирует отсутствие потерь данных и имеет солидное теоретическое обоснование. Но — очереди хранят данные, их нужно конфигурировать (в частности, роутинг между топиками), они могут переполняться, в них быть данные устаревшего формата/мусор(queue poisoning), их содержимое частенько сложно просмотреть, в системах на очередях требуются дополнительные усилия для того, чтобы связать запрос с ответом.
А в чем преимущество ZeroMQ перед обычным синхронным RPC в такой схеме? И как же гарантия доставки, особенно при падении брокера?
сначала мы любим микросервисы, потом мы их ненавидим, и потом понимаем когда и как стоит строить архитектуру основываясь на этой идее. Ну как с паттернами в целом.
Это я к тому что по дэфолту лучше монолит, см выше.
Если у вас уже все на сервисах, значит просто добавится сервис транзакций, который в том числе будет отслеживать целостность данных в течение всей транзакции и после нее. В монолите вам также скорее всего придется изрядно перекроить абстракции, чтобы добавить такой функционал.
по дэфолту лучше монолит, см выше.
С этим спорить не буду и полностью поддерживаю. Важно просто понимать когда микросервисы все же нужны.
Внезапно на ровном месте возникли распределенные транзакции между шардами.
между микросервисами. И решение для этой проблемы уже давно придумали — Saga и да это сложно (в рапределенных то системах). И да, каждый микросервис теперь должен уметь откатывать результат своих действий. И да, у нас сверху будет сидеть отдельный микросервис который трекает результат работы каждого и если где-то что-то пошло не так — просит откатиться.
Хм… интересно. А разве это работает не на уровне базы данных? Ну то есть… да. у вас есть та же распределенная касандра, и да вы моете там так сделать. Но у меня есть 2 микросервиса, один использует эту распределенную касандру а другой neo4j. Ну то есть… разве транзакции на CAS не расчитаны что у нас общая распределенная база данных?
Необязательно из-за этого связываться с распределенными транзакциями. Есть варианты попроще:
- Рефералы как-нибудь переживут, если из-за сбоя системы им недоначислят несколько посещений. Выбирая между временем разработки системы распределенных транзакций и небольшими потерями для нескольких клиентов раз в n месяцев… возможны варианты варианты.
- Использовать persistent queue. В случае с реферралами не так нужна атомарность и не нужна возможность отката транзакции — так что можно вместе с обновлением аккаунта послать в очередь сообщение о том, что надо обновить рефералов.
А вообще с деньгами надо аккуратнее обращаться. Понимать немного бухгалтерию, двойную запись, проводки. И строить архитектуру по аналогии с тем, как работают с финансами в реальном мире. Все-таки жизнь — она распределенная, асинхронная и транзакций там не предусмотрено :-)
Они работают быстрее ввиду простых факторов вроде компиляции.
Если говорить про NodeJS, то он компилирует JavaScript в нативный код во время запуска (с заглушками, правда). Компиляция в JVM-языках — это компиляция в байт-код. Чтобы он стал нативным кодом, необходим «прогрев» — JIT компилятор должен сообразить, что этот код горячий (вызывается часто), и только после этого происходит компиляция в нативный код. Это вовсе не является преимуществом в плане производительности.
Об этом в статье «Блеск и нищета микросервисов»
www.arbinada.com/ru/node/1651
1) проблема перекладывания ответственности решается чётко выраженными соглашениями о сервисе (SLA)
2) в условиях современной разработки сегодня тебе говорят, что это временный сервис, написанный под конкретную задачу, завтра это боевой сервис, который «должен пожить годик», послезавтра используется в десятках процессов. И в условиях микросервисной архитектуры намного удобнее править и оптимизировать то, что теперь приходится поддерживать.
3) преимущество микросервисов ещё в том, что из них можно очень быстро собирать разные бизнес-процессы так как ты просто говоришь владельцам сервиса — «С завтрашнего дня я буду давать Вам нагрузку 50 запросов в секунду, ок?» и всё, тебя не волнует ни оверсайзинг дисков сервера, который они юзают, ни количество шардов — ничего не волнует, заключил SL и вперёд — настраивать логику.
4) небольшой модифай моего 3го пункта — сборка сложных процессов за мизер времени, когда есть готовый винегрет сервисов представьте что Вам надо сделать процесс, который обслужит банально одно событие или должен поработать пару часов, но сложный, с разветвлённой логикой и кучей функционала. Либо писать монолит с кучей всего, либо забабахал процесс на корезоиде, который пару раз вызвал каждый сервис и всё — никогда больше туда не вернётся. Зато деньги в кармане и клиент доволен.
Микросервисы: пожалуйста, не нужно