Pull to refresh

Comments 111

Хм, как раз недавно был вопрос по поводу микросервисов.


Если кодовая база самого микросервиса относительно небольшая и он делает одну, но сложную задачу, а сам docker-образ вместе с зависимостями весит больше 5ГБ, это тоже будет микросервис?

Да, микросервис. Про микрообраз никто и не говорил :)

P.S. NodeJS? :))

Хм, мне кажется, количество зависимостей тоже должно быть в определении, но… нет так нет.


P. S. Нет, просто OpenCV + нейронные сети + еще какая-то штука и вуаля :)

UFO just landed and posted this here

Микро определяется областью ответственности а не размером. Вполне нормальный микросервис.

А ведь достаточно не зацикливаться на одном паттерне (на любом масштабе), а каждый раз думать что подойдет в конкретной ситуации. Зачастую самыми надежными оказываются гибридные решения. Монолит+микросервисы, наследование+композиция и т.д… Микросервисы вовсе не плохи во многих случаях, например, если хочется построить пайплайн для обработки потока данных, при этом по большей части обработчики не зависят друг от друга, то нет смысла делать их модулями в одном процессе, гораздо надежнее разнести на отдельные сервисы, каждый из которых можно независимо обновить/отключить.
«A Silver Bullet doesn't exist,» Steffen Blauenfeldt Otkjær
UFO just landed and posted this here
завтра еще какую-нибудь фигню придумают.
Уже придумали. Это Blockchain

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

UFO just landed and posted this here
Как вы считаете общее качество сервисов?
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
Так что мимо, совсем мимо.

Попробуйте попользоваться только этими картами. И потом сравните впечатления.

UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
Есть мнение, что без «супер-пупер-иновационных подходов» качество и/или функциональность сервисов было бы ниже. Грубо говоря, без них или функциональность была бы сейчас на уровне прошлого века, или качество бы было ещё ниже. Ну или и то, и другое. По сути все эти подходы — средство борьбы со сложностью, а сложность сервисов/продуктов постоянно возрастает.
UFO just landed and posted this here
На мой взгляд одним из важным достоинством микросервисов, это то что мы не привязываемся к одному языку программирования, что дает больше гибкости.

Мы можем переписать 1 сервис на другой язык, ну к примеру на java и протестировать как это будет работать. мы даже можем протестировать это на процентном соотношение, например «Сервис комментарий у нас на python, мы переписали его на java и пустили трафик 70/30» и померили что быстрей…

Такое невозможно сделать с монолитом.
UFO just landed and posted this here
И почему я вспомнил про Linux Kernel?
Ну вот у меня есть core. То, что осталось от монолита, по сути аутентификация и авторизация, неразрывно с ними связанное логирование и разные справочники, крайне редко изменяемые.
UFO just landed and posted this here
UFO just landed and posted this here
Собственно, да, у меня большая часть core не имеет специализации, что чётко ложилось на предметную область, то было выделено. Здоровые куски инфраструктуры были выделены. И просто осталось то, что нет смысла выносить ни в сервис (грубо — ради таблички из 7 строк поднимать СУБД, апп и веб-сервер, как-то лениво), ни дублировать в нескольких сервисах.

Если есть Core — значит на нем завязаны все (ну или большинство), он центр зависимостей. А такого не должно быть в рамках микросервисов, распределенная же система, децентрализованная. Это примерно как god object.

UFO just landed and posted this here
Хм.
А как сервисам между собой общаться? :)

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

Если же они будут безобразно ходить друг в дружку, то это только увеличение бардака, с которым мы якобы пытались бороться :)

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

вы сейчас описываете штуки вроде enterprise service bus и это тип устаревшая модель.


Обычно сервисы ходят друг в друга по сети, неиболее популярный вариант — старый добрый http. Многие используют штуки аля zeromq. То есть нет единого "сервиса" который знает как кто куда общается, ибо это сервис завязал бы всех на себе и являлся бы узким местом.


Если же они будут безобразно ходить друг в дружку, то это только увеличение бардака, с которым мы якобы пытались бороться :)

Именно друг в дружку. Если по аналогии, посмотрите картинку. В ней кружочки одинакого цвета представляют составные части микросервисов (у нас их на картинке 3) а жирные стрелочки между ними — это как они ходят по сети.


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


В общем, в неумелых руках любая технология будет порождать проблемы. :)

Согласен полностью. Микросервисы это последний тренд к сожалению. Модно это.

То есть нет единого «сервиса» который знает как кто куда общается
А если сервис на который завязаны другие, сменит ip/dns, ходить и вручную менять конфиги, или как?
это сервис завязал бы всех на себе и являлся бы узким местом.
Сделать несколько нод с репликацией, чтобы не быть узким местом.
А если сервис на который завязаны другие, сменит ip/dns, ходить и вручную менять конфиги, или как?

ну так… в чем проблема? Не надо завязываться на то что может резко поменяться и все) Ну а так да, можно сервис дискавери замутить.


Сделать несколько нод с репликацией, чтобы не быть узким местом.

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

UFO just landed and posted this here

Какая связь между DDD и применением разных ЯП в одном проекте?
Насколько я понимаю, если кусочек проекта может быть скомпилирован или задеплоен независимо от основного проекта, то это уже микросервис.

UFO just landed and posted this here

Продолжу кидать ссылки на видосики: Eric Evans — DDD & Microservices: At Last, Some Boundaries!. Тут хорошо раскрыта связь между DDD и микросервисами.


p.s. вы как бы и правы и нет. Ну то есть если вы проектируете монолит, вы можете париться о bounded context-ах но с микросервисами это выходит явно потому что… ну если этого не делать то все будет… плохо. Явные границы лучше неявных.


С другой стороны если разработчик не понимает как правильно сделать монолит — в микросервисах ему точно делать нечего. Микросервисы как бы… дают профит в плане масштабируемости. И если у вас база данных влезет на один сервер или команда не настолько большая что тесно, то наверное не стоит лезть в это болото.

В это болото можно и нужно лезть и из собственного интереса, но не на деньги работодателя(если он сам не просил, конечно), само собой, и уж точно после освоения базовых принципов DDD. Тогда:
а) Появляется представление о том, когда микросервисы не нужны, а когда будут вполне себе неплохим решением
б)+ к скилу проектирования(в т.ч монолитных приложений)
в) Практический опыт ДО реальной необходимости

Спасибо за видео!
Нужно заранее понимать, нужен ли сервис в данной ситуации или нет.
Иначе это напоминает перебор индекса массива (больше/меньше, строгое/нестрогое неравенство), чтобы программа заработала. :)
Понимания 0.

Мало у кого есть личные проекты (хотя это плюс, а то имеем сапожников без сапог), а тем более требующие микросервисов.

>Практический опыт ДО реальной необходимости

Это типа умение дрочить? :)

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

Кмк, вещи нужно использовать по мере необходимости и с пониманием.
У меня тоже был дурной опыт. Например, с ООП. Молодой неокрепший ум (+без опыта коммерческой разработки еще) начитался, что это круто: наследование тебе, инкапсуляция.
Ну и начал натягивать ООП (так был сделан, слава богу, только один подраздел).
На поверхности был как бы ООП. Но это был ад. Я код вообще перестал понимать. :)
Плюнул потом и переписал так, как понимаю.

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

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


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

Мало у кого есть личные проекты (хотя это плюс, а то имеем сапожников без сапог)


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

В реальности это все разобъется в пух и прах.


У меня например не разбилось, что я делаю не так?

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


Очевидно, однако, если ты пользуешься одними и теми же архитектурными принципами, то этот процесс будет, как минимум унифицирован. Вот был у меня DDD проект. Взял, да повыдергивал домены на микросервисы. Часа 2 заняло с учетом написания Dockerfile.

Фреймворки за вас это не сделают


Проектирование это и не задача фреймворков.

Это типа умение дрочить? :)

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

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

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

На поверхности был как бы ООП. Но это был ад. Я код вообще перестал понимать. :)

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

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

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

Та плевать, как кто делает

Ну это вообще какой-то вброс дерьма на вентилятор. Стандарты? Паттерны? Лучшие практики? Что объединят три предыдущих вопроса? Это именно то «как делают другие» и разработчику на это не должно быть плевать.

Не нужно свой код подстраивать под что-то, не понимая этого чего-то


Обратного никто не утверждал.

А также, наверное, не стоит советовать новичкам идти по пути непонимания и наименьшего сопротивления.


Этого им тоже никто не советовал, ну, во всяком случае, я точно не советовал.

Нужно меньше догм

Назовите хоть одну — уберем.

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

Для того, что бы у тебя появилось понимание, тебе нужно сначала их как минимум использовать :)

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

Обучение без необходимости — это дерьмо. Человек ни хрена не поймет.
Знания получил, думать не научился. :)
Прежде всего нужно учить думать.

>Разработчик без личных проектов — тоже самое, что адвокат без судебной практики.

Совсем не то. И это сплошь и рядом.

>У меня например не разбилось, что я делаю не так?

Может это Вам лишь так кажется? :)

>Проектирование это и не задача фреймворков.

Уже нет? Не они задают архитектуру? :)

>Первый раз мы решаем квадратное уравнение до реальной необходимости это сделать

Сравнение некорректное.
Решая квадратное уравнение мы решаем конкретную задачу: найти x.
Здесь же абстрактное обучение в вакууме.

Еще раз:
Есть потребность — делаем, нету — не делаем.
Не нужно искусственно что-то натягивать.

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

Программист, пишущий на фреймворках? :)
Та они (в основном) и шагу ступить без него не могут.

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

>Может всетаки дело не в необходимости а отсутствии у кого-то системного подхода к собственному обучению?

1. Я не считаю себя супер-программистом.
2. Необходимости в ООП не было, а я поддался моде. (Ну как вы советуете сейчас идти пилить микросервисы :) )
Если Вы применяли с пониманием (хотя Вы говорите, что без :) ) и оно было необходимо (хотя в случае с микросервисами Вы говорите, что нет), то ок :)

>ФУ, микросервисы мейнстрим, лучше буду дерьмо жрать с кучей инстансов монолитных приложений, зато НИКАК ФСЕ.

Я такого не говорил.
Я всегда говорю: Все нужно использовать по потребности и с умом! А не искать серебрянные пули.

>Назовите хоть одну — уберем.

Вы сами их упомянули:
«Стандарты? Паттерны? Лучшие практики?»
А также: ООП — тру (в последнее время: ФП — тру), фреймворки — тру, goto — зло.

Ну не везде это нужно и оправдано. Тем более без понимания.

>Обратного никто не утверждал.

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

>Ну это вообще какой-то вброс дерьма на вентилятор. Стандарты? Паттерны? Лучшие практики? Что объединят три предыдущих вопроса? Это именно то «как делают другие» и разработчику на это не должно быть плевать.

Разработчик, который не умеет думать, а использует готовую догматику, не понимает, что он делает.
На поверхности получаем якобы и стандарты, и паттерны, и практики, только оно такое говнокодное, что капец. Ну или несвязная копипаста из разных мест :)
Это обезьяна, а не разработчик.
Серебрянной пули нету, а вы всем ее суете.

>Для того, что бы у тебя появилось понимание, тебе нужно сначала их как минимум использовать :)

Нет.
Нужно читать стоящие книжки, смотреть примеры, делиться опытом.

Иначе это будет варение в себе.
На поверхности будут вроде и микросервисы, только сторонний наблюдатель подумает: ну нахера это тут?

Если человек применяет подход без понимания, то он обезьяна.

>В это болото можно и нужно лезть и из собственного интереса, но не на деньги работодателя

Я согласен, что заниматься экспериментами на деньги работодателя не стоит.
Я против этого и выступаю, когда крутые перцы говорят: а не переписать ли все на A фреймворк, а не поменять ли нам БД, а не добавить сюда еще эту приблуду.
Хотя необходимости в этом нет, просто им скучно.
Если же есть необходимость, то вряд ли ваш личный проект будет больше требовать разбиения на микросервисы (а они нужны не такому и большому количеству сайтов).
Я Вас помню из предидущих тем, мое прошлое сообщение — лишь послание тем, кто будет его читать. У меня нет никакой необходимости вам что-то доказывать) Уймитесь уже наконец. Добра <3

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


Мой личный проект в среднем обрабатывает 10к запросов в секунду, думаю, на этом можно закончить :D
1. Я тоже помню (фрагментарно) :)
2. Не нужно ничего доказывать. Я не стараюсь что-то доказать. Я стараюсь найти аргументацию, что для чего в каких случаях больше подходит, в каких случаях А может быть лучше Б, в каких нет.
В данном случае — в каких случаях и как стоит использовать микросервисы.
3. Если я в чем-то ошибаюсь, приводите аргументы. Но не детский лепет, который разбивается в пух и прах. (Это не только вам адресовано). Если укажете на ошибку, я будут только благодарен.

>Мой личный проект в среднем обрабатывает 10к запросов в секунду, думаю, на этом можно закончить :D

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

Но нужно смотреть, что скрывается за этими запросами. :)
Тут https://habrahabr.ru/post/262623/ тоже крутые цифры, а под капотом работа с первичным ключом одной таблицы.

Не надо экстраполировать свою самоуверенность на все отрасли человеческой деятельности.
Не надо экстраполировать свою самоуверенность на все отрасли человеческой деятельности.

Золотые слова. Возможно для вас они тоже должны прозвучать. Просто поверьте что в мире есть люди которые знают что делают.

1. А я и не говорил, что я не могу ошибаться. Перечитайте пункты 2,3, адресованные предыдущему оратору.
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, Яндекс… у них ставка сделана на архитектуру а не на ЯП.
UFO just landed and posted this here
ЯП (язык программирования) это инструмент, а инструмент нужно использовать по назначению.

Никто и не спорит, что язык надо подбирать под задачу. Это, можно сказать, уже стало мантрой среди программистов. И принцип этот, конечно же, правильный. Весь вопрос в том, что считать задачей. Чем она определяется? По сути, задача определяется, так называемым, условием задачи. Есть главное условие, собственно что нужно сделать, а есть уточняющие условия, накладывающие дополнительные ограничения, и добавляющие свою специфику. Так вот, наличие у компании уже готовой кодовой базы на каких-то языках, и специалистов, знакомых с определенными языками и технологиями, тоже является частью условия. И если какой-то язык или фреймворк более-менее подходит, и он уже используется в других проектах, то лучше не вводить новых сущностей. И тут нет никакого противоречия с принципом «инструмент под задачу». Мы как раз выбираем инструмент под нашу задачу. Не под какой-то архетип задачи, а под нашу конкретную задачу, учитывая все условия.
Что до крупных компаний, типа Google, то у них есть свои особенности, связанные с их размером. Наверное зоопарк технологий для них неизбежен. Но успеха они достигают вовсе не благодаря ему. Скорее уж вопреки. Ставка на архитектуру — это как раз инструмент борьбы с негативными эффектами от зоопарка.
И если какой-то язык или фреймворк более-менее подходит, и он уже используется в других проектах, то лучше не вводить новых сущностей.


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

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

В общем, однозначного «лучше» точно не может быть. Влияет на лучше слишком многое, чтобы давать универсальные советы.
Старению подвержены все… :)
Старение не так страшно, когда можешь сам омолаживать по необходимости (самопись).
В случае умирания фреймворка/CMS, выхода новой несовместимой версии поимеем боль :)

Зоопарк сложнее поддерживать.
Сотрудники слабо взаимозаменяемы.

Выгоды от зоопарка больше у крупных компаний.
Как всегда, истина где-то посередине. Микросервисы же не обязывают использовать себя для очередного блога. Весь вопрос в поставленной задаче. В любом случае всегда нужно включить голову и подумать.
Теперь осталось написать послание «unix-way, пожалуйста, не нужно» на бис.
Оригинал, если кому-то нужно http://basho.com/posts/technical/microservices-please-dont/
На оригинал можно перейти, если нажать на имя автора оригинала под переводом.
На мой взгляд, многие «недостатки» перечисленные в статье ровно так же свойственны и для монолита. К примеру, в #4 перечислены сложности с написанием интегрейшн тестов и «социальные проблемы» с ответственностью за баги. Что одно, что другое может быть свойственно и для микросервисов и для монолита. Приведение таких «недостатков» в поддержку своего мнения выглядит больше как «накидаю-ка еще на вентилятор».

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


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

Да, в принципе, всё совпадает с моим опытом использования микросервисов. Вот только статья совершенно не раскрывает вопрос "зачем тогда вообще с этим связываться".


Мой ответ — повторное использование уже сделанной работы. Рассматривайте микросервисы как библиотеки 2.0 со следующими преимуществами:


  • интегрировать микросервис проще, чем библиотеку. Никаких конфликтов, никаких зависимостей, никакой головной боли с конфигурированием. Есть сетевое API по известному протоколу.
  • библиотека позволяет повторно использовать алгоритмы. Микросервис позволяет повторно использовать еще и данные без многих недостатков интеграционной СУБД (см. Фаулера Integration database antipattern)
  • микросервисы, в отличие от библиотеки, позволяют скрыть свои зависимости от клиентов. Это позволяет писать как более гибкие, так и более устойчивые приложения. Например, микросервис отправки писем единственный хранит настройки email-сервера и может предпринимать дополнительные усилия по доставке писем.
  • как обобщение предыдущего пункта, микросервисы изолируют проблемы конфигурирования кода. Те же адреса SMTP, баз данных, JMS… Большой монолит частенько имеет весьма обширную конфигурацию.
  • гораздо богаче возможности по версионированию. Система может одновременно использовать несколько разных версий одного и того же микросервиса, если не все клиенты не готовы делать миграцию. Не разных версий API, а именно разных версий бинарника с несовместимыми API.

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

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

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

глубоких знаний системы

скорее понимание предметной области.

интегрировать микросервис проще, чем библиотеку

На мой взгляд — одинаково. Если библиотеке нужен был параметр конфирурации — то у микросервиса он никуда не денется, просто вы его сконфигурируете в другом месте.


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

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


гораздо богаче возможности по версионированию.

И гораздо сложнее протестировать все возможные варианты и сочетания версий.


Я в целом к тому, что даже если все эти преимущества вдруг реализуются в жизни (что бывает не всегда) — они все равно будут чего-то стоит. Т.е. это не бесплатно.

>> микросервисы изолируют проблемы конфигурирования кода.
> И кудаж они их девают по-вашему?

sarcasm on

Да все просто — добавляем микросервис конфигурирования всей инфраструктуры.

sarcasm off

К сожалению в крупных проектах так и делают.

Конечно не бесплатно, просто нужно выбирать решения, которые дают больше плюсов, чем минусов :-) По пунктам, местами гиперболированно:


  1. пусть нам нужно отправлять письма. В случае библиотеки мы имеем конфигурацию e-mail сервера в 10 местах и много работы при смене e-mail провайдера, в случае микросервиса — конфигурация одна, код интеграции с email — один
  2. service discovery. В рамках системы должен быть единый механизм поиска сервиса по имени и авторизации. В этом плане есть различие между внутенними сервисами (микросервисы) и внешними сервисами(почта/база/JMS/...) Т.к. первые контролируются вами, что означает унифицированный интерфейс, обратную совместимость, отсутствие хитрых параметров конфигурации и необходимости мигрировать на альтернативные реализации.
  3. Тестирование — это отдельный большой разговор. Вкратце, моё мнение — микросервисы должны тестироваться изолированно на соответствие своему контракту 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


У кого-то микросервисы могут ходить в одну базу / писать/читать одни и те же файлы.

в этом случае микросервисы превращаются в распределенный монолит. У вас узкое место (одна база данных) так и остаются.

У вас узкое место (одна база данных) так и остаются.

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

Узкое место не в смысле производительности, а всмысле точки влияния изменений.

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

В этом плане да, согласен.

>Специально для вас: Greg Young — Stop Over-Engenering

Мне влом смотреть 50 минут.
Вы хотите сказать, что я проповедник оверинжиниринга? :)

Вроде во всем спорах, в т.ч. с Вами, я выступаю против него. :)

>в этом случае микросервисы превращаются в распределенный монолит. У вас узкое место (одна база данных) так и остаются.

Плевать.
Нам что завести 2-100500 баз данных с пользователями для каждого микросервиса, который с ними работает?
Выйдет что-то на постном масле. :)

Блин, в прошлом моем комменте
«С таким успехом монолитом нельзя считать 2 системы, работающие на одном фреймворке. :)»
следует читать так:
«С таким успехом микросервисом нельзя считать 2 системы, работающие на одном фреймворке. :)»
Вы хотите сказать, что я проповедник оверинжиниринга? :)

Ну от части. И я тоже. Я думаю вам понравится, посмотрите)


Вроде во всем спорах, в т.ч. с Вами, я выступаю против него. :)

вот потому я ссылку и даю. Вопервых далеко не все ваши высказывания чушь) Во вторых — мы по разному трактуем оверинженеринг.


Нам что завести 2-100500 баз данных с пользователями для каждого микросервиса, который с ними работает?

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


И да, это сложно и для 99.9% проектов это не нужно. Но зато позволяет вам более гибко подходить к процессу разработки системы.

Сервис, как класс, если много торчит наружу, тора пора задуматься над рефакторингом :)
Микросервисы особенно хороши, если замешать все на каком-нибудь messaging в виде транспорта (для легкости broadcast/unicast обмена) и приправить auto discovery (для минимизации конфигурации зависимостей)

Банки любят такую архитектуру, т.к. она гарантирует отсутствие потерь данных и имеет солидное теоретическое обоснование. Но — очереди хранят данные, их нужно конфигурировать (в частности, роутинг между топиками), они могут переполняться, в них быть данные устаревшего формата/мусор(queue poisoning), их содержимое частенько сложно просмотреть, в системах на очередях требуются дополнительные усилия для того, чтобы связать запрос с ответом.

Просто взять любой message broker и использовать, как транспорт — много нерешенных проблем. Тут вы абсолютно правы. Очереди, конфигурация… Но варианты решения, все же, есть. Например, в своем велосипеде проекте у меня пока получилось использовать messaging (NetMQ, по факту, p2p), реализовать «синхронное» получение ответа на запрос и auto discovery, т.е., необходимо сконфигурировать только well-known адрес дискавери-сервиса.

А в чем преимущество ZeroMQ перед обычным синхронным RPC в такой схеме? И как же гарантия доставки, особенно при падении брокера?

Центрального брокера нет, p2p. Если нужно подтверждение доставки, можно указать callback и дождаться синхронно его получения, что не всегда надо. Discovery service использует broadcast для мониторинга состояния нод в сети, удобно было использовать PUB/SUB. В принципе, основная идея заключалась в использовании раутинга (только) на основании типа передаваемого сообщения (а также его версии), так что вариант с NetMQ казался наиболее подходящим.

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

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

Это я к тому что по дэфолту лучше монолит, см выше.

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

по дэфолту лучше монолит, см выше.

С этим спорить не буду и полностью поддерживаю. Важно просто понимать когда микросервисы все же нужны.


Внезапно на ровном месте возникли распределенные транзакции между шардами.

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

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

Необязательно из-за этого связываться с распределенными транзакциями. Есть варианты попроще:


  1. Рефералы как-нибудь переживут, если из-за сбоя системы им недоначислят несколько посещений. Выбирая между временем разработки системы распределенных транзакций и небольшими потерями для нескольких клиентов раз в n месяцев… возможны варианты варианты.
  2. Использовать persistent queue. В случае с реферралами не так нужна атомарность и не нужна возможность отката транзакции — так что можно вместе с обновлением аккаунта послать в очередь сообщение о том, что надо обновить рефералов.

А вообще с деньгами надо аккуратнее обращаться. Понимать немного бухгалтерию, двойную запись, проводки. И строить архитектуру по аналогии с тем, как работают с финансами в реальном мире. Все-таки жизнь — она распределенная, асинхронная и транзакций там не предусмотрено :-)

Я думаю автор пришел (предлагает) немного другое, не просто монолит, а «внутренних» сервисов на основе чистых, хорошо определенных модулей в коде", как бы микросервисы, но внутри, где внутренний микросервис можно будет легко* вынести во внешний. Хоть это и монолит, но его можно отнести к 3-му виду,
Зацепился глазом за одну неточность.

Они работают быстрее ввиду простых факторов вроде компиляции.

Если говорить про NodeJS, то он компилирует JavaScript в нативный код во время запуска (с заглушками, правда). Компиляция в JVM-языках — это компиляция в байт-код. Чтобы он стал нативным кодом, необходим «прогрев» — JIT компилятор должен сообразить, что этот код горячий (вызывается часто), и только после этого происходит компиляция в нативный код. Это вовсе не является преимуществом в плане производительности.
Статья выстраданная, но в ней не упомянуто, что это уже как минимум третья попытка продавать серебряную пулю архитектуры систем из микрокомпонентов.
Об этом в статье «Блеск и нищета микросервисов»
www.arbinada.com/ru/node/1651
На своём примере (работа в большом банке с тысячами сервисов):

1) проблема перекладывания ответственности решается чётко выраженными соглашениями о сервисе (SLA)
2) в условиях современной разработки сегодня тебе говорят, что это временный сервис, написанный под конкретную задачу, завтра это боевой сервис, который «должен пожить годик», послезавтра используется в десятках процессов. И в условиях микросервисной архитектуры намного удобнее править и оптимизировать то, что теперь приходится поддерживать.
3) преимущество микросервисов ещё в том, что из них можно очень быстро собирать разные бизнес-процессы так как ты просто говоришь владельцам сервиса — «С завтрашнего дня я буду давать Вам нагрузку 50 запросов в секунду, ок?» и всё, тебя не волнует ни оверсайзинг дисков сервера, который они юзают, ни количество шардов — ничего не волнует, заключил SL и вперёд — настраивать логику.
4) небольшой модифай моего 3го пункта — сборка сложных процессов за мизер времени, когда есть готовый винегрет сервисов представьте что Вам надо сделать процесс, который обслужит банально одно событие или должен поработать пару часов, но сложный, с разветвлённой логикой и кучей функционала. Либо писать монолит с кучей всего, либо забабахал процесс на корезоиде, который пару раз вызвал каждый сервис и всё — никогда больше туда не вернётся. Зато деньги в кармане и клиент доволен.
Sign up to leave a comment.

Articles

Change theme settings