Как стать автором
Обновить

Комментарии 106

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

А как же требование почти во всех вакансиях для бэкэндеров, это работа с микросервисами и докером? Вот и суют люди это там где надо и там где не надо, чтобы в тренде быть.

У нас такое "будет плюсом" есть. Микросервисы и докеры — нормально. docker-compose очень многое закроет. Может даже docker swarm в кластере из нескольких нод, если реально нужна отказоустойчивость и/или распределение нагрузки по нодам. У нас даже k8s есть в "будет плюсом" вроде бы. Но это уже чтобы с девопсом нормально взаимодейстовать.


В общем, если решили перейти на докер, то начать с docker-compose, потом docker swarm, только потом k8s, может посмотрев сначала на настройки над ним, прячущие большую часть его сложности. Поработав с полгода с кубером, убедился в высказывании (недословно) "k8s — это не оркестратор, это фреймворк для сборки оркестраторов"

Docker-compose на проде это приключение не для слабонервных. Docker тянет за собой необходимость оркестрации на проде. Не обязательно кубер. Если не покупать кубер у облачных провайдеров я за nomad. Так как поддерживать кубер самостоятельно для небольшой организации просто нереально. Поэтому сейчас и ездят по миру прославленные спикеры которые трпят за докер и микросервисы. А на деле за aws, google или digitalocen, к услугам которых придется прибегнуть после неудачных попыток реализовать микросервисы на докере своими силами. Но микросервисы архитектура может быть даже круче и удобнее без всего этого. Например есть стандарт wamp не путать с аналогом денвера. Я думаю этот стандарт незаслуженно почти забыт и у него будет еще свое место в истории

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


Наверное очень забытый, раз даже вики о нём не знает, можно ссылочку какую-нить? А то только с денвером и вебсокетами ассоциации.

Проблемы начинаются при обновлении. Без даунтайма сложно компоузом делать замену контейнера. А если еще к тому же что-то пойдет не так. Я для себя сделал вывод примерно такой. На проде или докер+оркестратор или без докера.


По базам данных — после того как у меня при рестарте контейнеров начал рушиться постгрес — никогда на докере. Я так понимаю что кроме каталога data который можно вынести на том, базы данных могут писать еще временные файлы в другие каталоги. И если повезет можно попасть на краш. Аналогичную историю мне рассказал один опытнейший DevOps только по MySQL серверу.

Забыл упомянуть про zero downtime и прочие rolling updates отдельно — это тоже не к docker-compose. Ну и продакшен баз данных никогда под докером не держал, и даже на том же хосте не доводилось как-то.

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

У вас есть на выбор blue-green или же просто завести две ноды. И то и другое спокойно решается при помощи условного docker-compose + nginx/traefik.


По базам данных — после того как у меня при рестарте контейнеров начал рушиться постгрес — никогда на докере.

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

Мне хватило одного раза чтобы отказаться. Хотя два проекта под mysql у меня уже не один год под докером. Думаю дело во временных файлах которые могут быть в директории /tmp или еще где то. Возможно я попал на очень редкое стечение обстоятельств. Но зачем рисковать после этого?


См. Например https://thehftguy.com/2016/11/01/docker-in-production-an-history-of-failure/

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

везло, 100%.


У вас есть на выбор blue-green или же просто завести две ноды. И то и другое спокойно решается при помощи условного docker-compose + nginx/traefik.

ansible? в топку компоуз

везло, 100%.

И чувакам из Zalando тоже везло. И еще куче людей. Как в мире много везения, не находите?)


ansible? в топку компоуз

Тут есть два нюанса:


  1. docker-compose.yml из-за того, что его можно шаблонизировать через тот же ansible позволяет реализовывать сложные развилки в духе "использовать хостовую сеть или конкретный bridge" куда проще, альтернативой будет разве что развлекаться с несколько этапными вызовами модулей ansible, но тут есть второй нюанс
  2. Ребята из ansible умудряются ломать хотя бы один из модулей docker_* семейства (не docker_service/docker_compose) с завидной регулярностью. То рестарт контейнера через docker_container пересоздает его, то docker_network необратимо ломает сеть для всего хоста. В какой-то момент я просто устал и переписал все на docker-compose + его вызов через модуль ansible.
Тут есть два нюанса:

я saltstack юзаю с докерами — проблем нет. Касательно ансибла решение же простое — запинить версию, как и любого инфраструктурного решения. Те же docker-compose с докером от версии к версии подкидывают сюрпризы. И не надо мне говорить, что их никогда не бывает — начиная от того, что sysctl надо на хосте выставлять для какого-нибудь эластика и кончая странными эффектами при работе с nvidia-runtime. Я даже видел пацанов на центоси с докер 1.13 :-(


С компоузом прекрасный баг — https://bugs.launchpad.net/ubuntu/+source/docker-compose/+bug/1792824 и это не первая и не последняя история, чтоб их, чертовых смузихлебов


И чувакам из Zalando тоже везло. И еще куче людей. Как в мире много везения, не находите?)

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

я saltstack юзаю с докерами — проблем нет.

У saltstack, если я правильно помню, файл с тасками тоже по факту шаблон, это убирает проблематику первого пункта, например :)


начиная от того, что sysctl надо на хосте выставлять для какого-нибудь эластика

Это, кстати, вообще не проблема докера :) Это эластик сам развлекается и если запустить его вне контейнера такая же фигня будет.


Ну, мне как-то везло и мне docker-compose не подкидывал сюрпризов.


И с постгресом они сами говорят, что есть нюансы.

К сожалению, с ним нюансов полно и докер не самый первый в очереди :(

Это, кстати, вообще не проблема докера :) Это эластик сам развлекается и если запустить его вне контейнера такая же фигня будет.

ну, это скорее к вопросу того, что докер — это, по мнению разрабов, изоляция уровня Бог, что в корне не так )

Ну, если они не читают документацию, кто им доктор :(

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

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

В облаках «свой» кубер на виртуалках. За 2,5 года работы с кубером уже с многими проблемами столкнулся и набил кучу шишок. За последние 8 месяцев 2 или 3 раза проблемы были и решались в пределах 15 минут. На самом деле кубер изначально кажется сложным. После нескольких развертываний кубера руками начинаешь понимать его внутреннее устройство и оно достаточно простое для понимания одним человеком. Последний мой косяк был, решил не заставлять ждать разработчиков, пока доеду до работы, а через web-консоль запустить остановленные ноды дев-стендов и случайно их удалил. Кнопки «Start» и «Delete» находятся рядом. Через 3 минуты понял это и через 5 минут вернул их обратно по средствам terraform.
На самом деле кубер изначально кажется сложным. После нескольких развертываний кубера руками начинаешь понимать его внутреннее устройство и оно достаточно простое для понимания одним человеком.

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

А в "поддерживать" что входит?

Развертывание/обновление кластеров.
Решение проблем на дев-стендах разработчиков, тоже в кубере. Написание разных тулз(admission controllers/crd), позволяющих автоматизировать некоторые операции по работе с кубером.
Так как у нас есть on-premise поставка нашего продукта, то приходится заранее окружение заказчика воспроизводить и пробовать деплоить/править наши чарты.
Прод и инфраструктурный кубер… там особо нечего делать, они просто работают. Недавно «отвалилась» одна нода, так клиенты даже не заметили.

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

Создать дев/тест-стенд могут сами разработчики, всё это реализовано в CI, по нажатию одной кнопки. Логи и мониторинг прикручиваются автоматом. Если нужен стенд с определенным набором контейнеров или собрать стенд из определенной ветки, тогда можно запустить в ручную пайплайн с нужными настройками. И если надо очень специфичный кейс, тогда развертыванием занимаюсь я и это занимает не более 20 минут. Для поддержания множества чартов использую в основном vscode и несколько скриптов. У нас штук 5 шаблонов чартов, которые мы используем, но если было бы 100500 шаблонов, тогда мы сами себя обрекли на муки. Я бы не успевал их создавать, а программисты из-за меня не могли бы деплоить. По этому они учитывают мои требования, а я их.

Хорошо у вас :)

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

Только не на bare metal. Для поддержки куба на баре метал нужна целая команда инфраструктурщиков

Не скажу насчёт k8s, но считать, что микросервисы — это только для организаций, у которых «в штате 500 разработчиков»? Странно.
По мне, так даже при индивидуальной разработке такой подход мозги прочищает и помогает придерживаться хорошей архитектуры. А ещё помогает отдельные куски проекта поручать фрилансерам, неважно, какой язык программирования они используют, и устанавливать понятные критерии тестирования и приёмки их работы. Что как раз для небольших проектов очень актуально.

Я бы предпочёл работать над продуктом со второй картинки, с несколькими кучками дерьма с чёткими границами :)

Думаю вы не представляете насколько это сложнее. Четких границ нет нигде, а вдобавок куса «лишних» геморроев.

Все дело в том что н к о не реализует тру микросервис. Все просто пилят монолит на несколько ко монолитов меньшего размера. Поэтому получается еще хуже. Т.к. у монолита по крайней мере все в пределах одного приложения. А прираспиле на несколько они рано или поздно начинают общаться между собой иногда по кругу в пределах одного запроса.

То есть на микросервисы распилить можно, а на модули нельзя?

Там основная проблема — апи между сервисами. Если оно сделано не идеально — будет очень больно. В монолите можно предупредить всех и ночью накатить огромный патч на кодовую базу (поменять имена методов, разделить и тп). С микросервисами хреновое апи будет годами болтаться в кодовой базе (у нас к примеру 4 микросервиса отправки смс за 6 лет… хотели как лучше, а получилось вот так).

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

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


Проблема в том, что в монолите очень легко нарушить изоляцию столькими способами, что потом и вспомнить их все не получится .


(у нас к примеру 4 микросервиса отправки смс за 6 лет… хотели как лучше, а получилось вот так).

И вы за 6 лет не смогли все перевести на один? Печально :( С другой стороны у вас всего 4 микросервиса за 6 лет, что не так уж и плохо, учитывая, что различные АПИ вызваны, скорее, различным набором требований. У нас просто такая ситуация, тоже будем переделывать апи для сервиса смсок, так как появились новые требования к нему :(

Проблема в том, что в монолите очень легко нарушить изоляцию столькими способами, что потом и вспомнить их все не получится .

Зато все эти способы можно найти глядя в код. А в микросервисах даже этого может не получиться.

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


Зато все эти способы можно найти глядя в код.

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

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

У нас около 80 микросервисов. Чтобы заменить первый sms микросервис, нужно изменить других 5 микросервисов… долго… отложили на потом, пока новые будем писать с новым. И так пару раз. Ничего критично, просто жизнь. Больно большей частью DevOps парню… код не меняется, но следить 24/7 за всем этим нужно постоянно.


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


Оглядываясь назад, лучше бы пытались свести все максимум к 5-8 микросервисам пожирнее. И рефакторить удобнее, и команда не тормозится, и админить проще.

А мне кажется микросервисы наборот пощряют говонокодить. Принцип же такой что все приложение поделено на мелкие куски, очень мелкие и якобы не нужно особо следить за архитектурой потому-что кодовая база каждого сервиса очень маленькая и нет смысла лепить по три слоя и применять миллион паттернов. Но я честно говоря микросервисы не разу не видел, как и большинство моих коллег, поэтому могу судить только по книжкам)
Наговнокодить можно и в Hello, World'е, и в самом монструозном монолите.
У меня другой довод в их пользу — снижение количества ситуаций «в одном месте что-то поменяли — в другом работать перестало, а почему оно так — знает только Вася, которого нанимали 3 года назад и контактов не осталось». В крайнем случае отдельный микросервис можно переписать с нуля быстро и недорого. А вот как в случае, когда вместо «команды» — периодически привлекаемые фрилансеры, организовать разработку монолита так, чтобы он не превратился в кашу из костылей, — вопрос…
Я бы сказал это невозможно) Я видел штук пять монолитов крупных проектов и все они состояли из костылей=) да собственно на одном из таких я сейчас и работаю)
Да, все же вы правы, переписать маленький сервис однозначно проще, даже например поменять язык если найдется кто-то кто сделает это дешево, но не на том языке что применяется в компании.
Есть ли смысл применять микросервисную архитектуру на проектах из нескольких человек?

Зависит от этих человек. Скорее нет, если это не фулстэки.

В микросервисах тяжело хорошо [пере]определять границы сервисов. Тяжелее с consistency. Тяжелее работать с ошибками в отдельных сервисах. Рефакторинг архитектуры требует намного больше координации. Намного больше дублирования. Связи в OAS требуют больше церемоний (работы). Фрилансеры так и так сделают хуже, но с микросервисами легче залезть в вязкий техдолг.
Монолит проще и гибче. Интерфейс класса намного проще поменять, чем явные и неявные контракты API. Выделять хорошо спланированные доменные контексты (DDD) в микросервисы можно довольно быстро. Выделение плохо спланированных контекстов, скорее всего, приведёт к неестественным сложноподдерживаемым микросервисам. Если нужно разбить приложение на микросервисы, то проще и надёжнее всего начать с приведения в порядок монолита. Но это обычно следствие роста и усложнения, начинать с дорогих микросервисов с неустоявшимся ТЗ в мире, где 90% бизнесов быстро умирают, по-моему, растрата ресурсов.

плюс микросервисы — это куча обвязки, которую нужно втащить (мониторинг, логирование и пр), но она может быть универсальная, взаимодействие по сети (со всеми плюсами и минусами), возможность масштабирования ( и мы рано или поздно упремся в БД, если это не микросервис, который показывает просто картинки с котиками )
монолит — все-таки локальные вызовы

Начнем с того что вам нужен будет девопс и инфраструктура а это уже много денег и людей. Поэтому скорее нет.

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

Ну не говнокодить а использовать более простой подход. Я об этом в свой статье недавно писал — habr.com/ru/post/493426
Для разбиения приложения на части не всегда требуется физически его разделять.
За все языки не скажу но у Java есть множество вариантов:
Jigsaw, OSGi, или Maven-modules…

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

Микросервисы в прямом своем виде. То есть одна функция один микросервис. Ко орые общаются между собой по — внимание — http протоколу самый большой кошмар который может быть представлен. Хуже только система управления ядерным реактором из веб браузера.

Использование любого подхода до добра не доведёт, если отключать при этом мозги :)
«Одна функция — один микросервис» — это уже не «в прямом виде», а какой-то микросервисный радикализм. Я бы сказал (в терминологии domain driven design), что разумный подход для начала проектирования — «один ограниченный контекст — один микросервис». А потом ужé уточняем возможность и целесообразность такого разбиения с учётом требований к производительности, latency, пропускной способности и прочая и прочая.
Распределенное приложение тяжело написать качественно.

Как раз нет. Монолит качественно написать в разы труднее. Но вот написать абы как проще, это да.

Как раз нет. Монолит качественно написать в разы труднее.

Как раз да. Для команды из 5 человек (пример из статьи) монолит будет гораздо быстрее в разработке и в разы легче в поддержке. С ростом объема проекта и команды микросервисы начинают брать свое.
А «качество» во-первых субъективный параметр, во-вторых от архитектуры не зависит. Говнокод в микросервисах встречается ничуть не реже.
«Качество» приложения определяется очень просто — стоимостью последующих изменений.
Если стоимость следующего одного изменения дороже предыдущего, то «качество» так себе.

Стоимость изменений в микросервисной архитектуре имеет потолок — стоимость переписывания с нуля одного сервиса.
Для монолита такого потолок — переписывание с нуля всего монолита.

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

стоимость переписывания с нуля одного сервиса

Ну конечно. Простой пример, вы пишете микросервис, к которому обращаются другие сервисы (например, авторизация). Вы в нем накосячили или пришли новые требования и вынуждены изменить api для взаимодействия с ним. Чем это кончится? Переписыванием всех микросервисов, которые к нему обращались.
В монолите, особенно если он нормально спректирован, скорее всего правки будет сделать гораздо легче. Скорее всего все взаимодействие будет вынесено в одно место + ide подскажет где происходят вызовы и т.д.
В микросервисах же все прекрасно. Надо не забыть обновить ВСЕ микросервисы. А, как выше писали уже, что вот как здорово, можно на разных языках писать и это только добавляет боли.
В монолите, особенно если он нормально спректирован

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


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


  • Хочется обновить интерфейс взаимодействия с моделями
  • Обновили
  • Поменяли все места, где оно используются.
  • Вы замечательны
  • Деплоите
  • Оказывается, что в 3 случаях из 5 предыдущий разработчик клал на этот интерфейс и работал напрямую с моделиями.
  • Переписали
  • Деплоите
  • Оказывается, что другой предыдущий разработчик был большим фанатом отсутствия связности, поэтому он вытягивал модель из реестра, а на импортом, потому IDE ее не смогло найти
  • Переписали
  • Деплоите
    ...

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


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

разработчик клал на этот интерфейс и работал напрямую с моделиями

Это как раз пример плохо спроектированного монолита. Логическое разбиение (модули) никто же не отменял
поэтому он вытягивал модель из реестра, а на импортом, потому IDE ее не смогло найти

Это примерно тоже самое, что один микросервис лезет напрямую в БД другого микросервиса.
профиты скалирования и так далее

И так далее это что? Опять же, я если что, про небольшие проекты и команды в 5 человек. Там скорее всего и скалирование не потребуется. Для больших команд и проектов микросервисы — хороший выбор.
Это как раз пример плохо спроектированного монолита. Логическое разбиение (модули) никто же не отменял

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


Это примерно тоже самое, что один микросервис лезет напрямую в БД другого микросервиса.

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


Опять же, я если что, про небольшие проекты и команды в 5 человек.

Как команда из 5 человек может писать небольшой проект?( Мне кажется, что 5 человек это уже довольно много все-таки.

Как команда из 5 человек может писать небольшой проект?(

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

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


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

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

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

Можно, просто вместо масштабирования отдельных модулей, масштабировать весь монолит. Поставить, например, 10 серверов с 8 ядрами и 16 Гб памяти, там где можно было бы обойтись пятью с 8 ядрами и 1 Гб памяти (с большим запасом) и пятью с одним ядром и 16 Гб памяти.

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

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


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

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

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

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

его необходимость переоценена

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

будущее может и не наступить (мы, например, фигачим PoC или MVP, а он не взлетел по объективным причинам)

Чуть выше я написал, что обычно начинать с микросервисов неоправданно. Но факт того, что это инвестиция не отменяет. Но, как изветно, далеко не все инвестиции удачны. Иногда надо фиксировать убытки.

С дисциплиной проблемы? :) Сложнее в качественном монолите только удерживать себя от соблазна обращаться к внутренностям (включая таблицы базы) соседних модулей напрямую, а не через их фасад, который DTO принимет/отдаёт.


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

С дисциплиной проблемы? :) Сложнее в качественном монолите только удерживать себя от соблазна обращаться к внутренностям (включая таблицы базы) соседних модулей напрямую, а не через их фасад, который DTO принимет/отдаёт.

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

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

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

Можно подумать, в монолите не бывает случаев, когда нарушается нормальная форма и приходится страдать со всем этим чудом? Да в каждом втором :)

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

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

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

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

это не масштабирование ) это скорее просто "горячий" резерв (ну, т.е. 2-3 доп инстанса). Потому что если вам прилетит 300% трафика, то даже с таким резервом вы все равно не вывезете (тем более, если чего-то при этом отлетит).


p.s. да, айти — это дорого. Очень дорого. Либо дешево и тяп-ляп

От трафика и системы зависит.

Давайте определим «многие места». Мои наблюдения говорят, что большая часть софта это enterprise для 20-200 юзеров с нагрузкой 5 запросов в минуту.


Неочевидно, почему горизонтальное масштабирование монолита дороже. Положим у меня 1 монолит, у вас 10 микросеовисов. Вы запустите 4 экземпляра сервиса X, я запущу 4 экземпляра монолита, у которого будут вызывать функцию X. Разница будет только в размере бинарника. Хотя в данной ситуации я бы уже думал о движении в сторону распила монолита на X и «не X».


Масштабирование и отказоустойчивость это совсем разные вещи. Особенно хорошо это в БД видно, где есть hot-standby и master-slave.

Монолит обычно потому и монолит, что он жрет 10ГиГ памяти, кучу процессоров и грузится 5 минут (пока данные вкачает, кэши прогреет и кучу всего)… А микросервисы — они же маленькие ))))


Масштабирование и отказоустойчивость это совсем разные вещи. Особенно хорошо это в БД видно, где есть hot-standby и master-slave.

++

То есть запустили монолит и он не получив ни одного запроса сожрал 10 гб памяти? Странно это, скорее будет так — есть монолит, который жрет 10 Гб и есть 10 микросервисов, каждый жрет 1 Гб. Я не вижу причин, почему монолит должен суммарно больше памяти потреблять.

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


есть монолит, который жрет 10 Гб и есть 10 микросервисов, каждый жрет 1 Гб.

возможный сценарий. При этом еще и каждый микросервис тащит с собой свое окружение, свой рантайм и свою копию данных — так что МОЖЕТ БЫТЬ (но не факт) что 10 микросервисов даже скушают памяти больше, чем монолит.

@geocube VolCh понятное дело, что у монолита можно «обрезать» прогрев ненужных кешей и прочую загрузку данных, которая ненужна и жрет память. Думаю мы согласимся с тем, что запустить вторую копию монолита, в котором будет нагружена только часть функций и при этом не инициализировать части, которые не нужны — вполне реализуемая задача. Также не вызывает сомнений, что решение такой задачи сильно проще, чем полный распил монолита на микросервисы.


Я для себя вывел такой алгоритм


  1. Начинаем с монолита.
  2. Через годик просматриваются части, которые не меняются, относительно изолированы, обладают стабильным интерфейсом. Это кандидаты в отдельные сервисы, возможно без приставки «микро».
  3. Продолжаем в том же духе с другими частями системы. Опять же, никакого upfront design, пусть жизнь покажет где границы модулей.
  4. Если наступит момент, когда за железо платим больше $1 000 000 в год, можно думать о кубе, как о способе эффективнее и гибче это железо использовать. Нанимаем человека на $100 000, отбираем права на закупку железа у всех и даём им куб. Тогда есть шанс сэкономить немного.

Предвижу возражение — «куб решает кучу проблем». Он создаёт их не меньше, самая большая — его надо хорошо знать, а это минимум книжка на 600 страниц, которую каждый причастный должен освоить. Голословно, но предположу, что за год каждый разработчик потратит месяц чистого рабочего времени на изучение и борьбу с кубом и связанной экосистемой.

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


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


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

Немного не так. Запустили 10 инстансов монолита, каждый сожрал 10Гб. Итого 100 Гб. Запустили 3 инстанса одного микросервиса, каждый сожрал 1 Гб и запустили 7 инстансов второго микросервиса, каждый сожрал 9 Гб. Итого 66

Очень, очень много кода

Продукт, который берет на себя управление контейнерами, service discovery, load balancing, умеет отрабатывать логику проверок и гибко настраиваемый control-plane не может быть простым.
Чем больше вы приобретаете в Kubernetes, тем сложнее становится нормальный процесс разработки: вам нужны все эти концепции (Pod, Deployment, Service, и т.д.) просто чтобы ваш код заработал.

IaC никогда не был простым. Это он ещё не затронул вопрос про сети.
— Хм! А если без кубера?
(кратко)
1. Развернуть сервер, на котором будет развернуто наше приложение.
2. Установить на него необходимо программное обеспечение.
3. Деплой нашего приложения и конфигов.
4. БД
Сколько придется написать например, строк yaml-а в Ansible или Terraform?

— А если надо сделать отказоустойчивое решение? Тогда:
(кратко, упрощенно)
1. Развернуть 2 сервера.
2. Установить необходимое программное обеспечение + балансер (обмен файлами и редисы лучше опустить).
3. keepalived + Virtual IP (если это возможно, в некоторых облаках они отправляют тебя на свой балансер, за который надо дополнительно оплачивать) или DNS rr.
4. Деплой нашего приложения и конфигов.
5. БД + БД.

А если у нас микросервисная архитектура приложения? Тогда добавится Consul (Service Discovery) + Consul template.
А теперь у нас ползет нагрузка и сервера начинают «залипать»? Добавить ещё один сервер займет много времени. Кубер это делает за считанные секунды в случае с контейнерами и считанные минуты в случае с дополнительными нодами. И самое главное это повторяемость, в случае «простого подхода» от автора мы легко можем получить ответ на одном сервере 500, а на другом 200 из-за небольшого отличия в окружении.
Например, nginx может делать health checks рабочих процессов

Видимо Nginx Plus.
Если же вся ваша команда состоит из 5 человек, у вас 20 микросервисов и обстоятельства непреодолимой силы не вынуждают вас создавать распределенную систему, то где-то вы просчитались. Вместо 5 человек на 1 микросервис, как у больших компаний, у вас получается 0,25 человека.

Но мы небольшая компания (пока) и можем позволить только 1 чел на 5 микросервисов.

Для тех кто не хочет писать манифесты: мейнтейнеры кубера повернулись лицом к разработчикам и в свои «Очень, очень много кода» вложили команды kubectl run/create… -o yaml --dry-run, которые позволяют генерить манифесты одной командой. А с флагом --help они поведают о практически всех возможностях этих простых команд.

Статья от «паровозика который не смог». Nomad как альтернатива всем страданиям.
PS Перевод немного хромает.

Где можно посмотреть как с помощью kubectl run/create поднять и регулярно обновлять систему из пары десятков сервисов в связке на хотя бы двух окружениях (прод и тест) с "умным" копированием с теста на прод после апрува? А то может зря я писал пару десятков хелм чартов, настраивал helmfile и т. п. чтобы хоть как-то совладать с порядка 500 манифестов (5 окружений, 20 сервисов, в среднем 5 на сервис)?

Ни где! Для простых/пет проектов подойдёт.
Для тех кто не хочет писать манифесты… kubectl run/create

В статье не упомянуты helm и им подобные, а то и здесь было бы сравнение go-template и Jinja2 (тут бы я его поддержал).
А зачем что-то копировать с теста на прод? Вроде как все пытаются прод скопировать.

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


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

А если у нас микросервисная архитектура приложения? Тогда добавится Consul (Service Discovery) + Consul template.

кубер не отменяет необходимости использовать кучу СТОРОННИХ решений. Потому что тот же сервис дискавери и балансировка в кубере — она подходит только для определенного класса задач — иначе приходится тащить тот же консул и строить балансировку самому. Аналогично с хранением секретов. Секреты в кубере в base64? Srsly? Тащим vault и получаем нормально управление жизненным циклом секретов, acl и все прочее
Что еще. Балансировка входа трафика в кубер. Что там? Ах, да — надо тащить MetalLB тот же, потому что на бареметал этот вопрос не продуман от слова совсем.
Блю-грин, канари и прочее — нет встроенных примитивов. Rolling Update Strategy костыль, причем лютый, который покрывает только базовый случай — нормальный A/B (или blue/Green) на нем не собрать, поэтому и появляются продукты вроде Flagger, в опеншифте там свои штуки и многое другое

НЛО прилетело и опубликовало эту надпись здесь

Разработчики будут несколько десятков контейнеров руками или башам на своих машинах оркестрировать?

НЛО прилетело и опубликовало эту надпись здесь

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


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

НЛО прилетело и опубликовало эту надпись здесь

Видимо у меня руки не прямые. Пробовал я ансиблем решать задачи типа на развернутой среде поднять контейнер с новой версией приложения с новыми конфигами, дождаться пока отвечать начнёт, переключить на него трафик, погасить контейнер со старой версией. Или при появлении ветки feature/abc-123 в гит-репе развернуть новую "среду", отвечающую на домены *.123.test.example.com. Вот честное слово, лучше на баше. Так и остался ансибль только докер машину развернуть для кластера, и базу.

НЛО прилетело и опубликовало эту надпись здесь

Про базу с text полями если это postgresql то это как раз best practic

НЛО прилетело и опубликовало эту надпись здесь

Имеется в виду text вместо varstring

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

У меня обратный опыт, скорость работы сильно выросла когда выкинули кубер. Причина простая — раньше разработчик ничего не мог сам сделать, нужно к девопс бежать и объяснят, а затем ждать пару дней, пока у них время на это появится. А делов обычно на пару часов. Но ради этих пары часов разработчику внезапно нужно: docker, gitlab ci, helm, go, k8s. Docker и gitlab ci ещё куда не шло, но остальное это тысячи страниц документации, без которых даже элементарные проблемы решить затруднительно.


В нашем случае мы сначала потратили 3 месяца в попытке с k8s разобраться, получили рабочий деплой, но поняли что за этим нужно каждый день следить и подкручивать, стоит это от 250 тыс. в месяц. Решили нанять специализированную компанию, но вот беда — они ничего в нашем бизнесе не понимают и не очень хотят. В итоге через год мучений переехали на terraform + ansible.

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


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

Часто наблюдаю такую тенденцию. Внутри организации возникают группы или даже отдельные разработчики которые начинают внедрять на своих проектах элементы девопсинга. При этом конечно не согласованно. Это как всегда приводит к зоопарку. Попытка нанять специализированного девопса и привести зоопарк в порядок сталкивается с определенными трудностями. Так как сложно ломать сложившийся порядок. Каждый из руководителей направления считает свой способ лучшим и идеальным.

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

+++ и столкнуться с ограничениями кубера там — типо — хотите новый ингресс — заказывайте новый LB за денюжку в облаке (я утрирую, если что)

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