Комментарии 41
В самом базовом понимании нам нужно просто записывать текст в разные файлы.
Я люблю писать разнообразные логи в текстовые файлы. Это удобно. Это быстро. Их легко просмотреть или распарсить. Но это ненадежно. Можно свалить в текстовые файлы кучу отладочной информации, потеря которой некритична. Но мне представляется глубоко ошибочной идея писать туда информацию о бронировании и оплате. Если несколько процессов на одной машине пишут в один файл, то придется заморачиваться флоком. Если же пишут несколько процессов с разных машин, то сложности плавно перерастают в ранг проблемы. Можно, конечно, писать через syslog-ng, который умеет собирать логи удаленно, но тогда уж проще сразу взять СУБД и не мучиться.
Однако тут уместнее говорить о переход от SaaS-решения к своему. Например, чтобы снизить процент комиссии.
Вот с этого момента поподробнее, пожалуйста. Вы предлагаете написать свою платежную систему? Или отказаться от услуг платежного агрегатора и своими силами заключить множество договоров и подключить множество платежных систем у каждой из которых свой API, поддерживать обновления и разбираться с кривыми транзакциями? Для какого-нибудь гиганта с многомиллионным оборотом — это, конечно, разумный ход, но как это сочетается с примитивизмом, описанным в первой части статьи?
В итоге каждый из 6 компонентов будет обслуживать 1-3 разработчиками
Двенадцать разработчиков на постоянной основе для одного сервиса аренды недвижимости?
Двенадцать разработчиков на постоянной основе для одного сервиса аренды недвижимости?
Соль микросервисов в том, что это не обязательно должны быть разные люди. У нас при похожей схеме всего 5 разработчиков.
P.S. А логи, кстати, очень удобно хранить на внешнем сервисе, например, Logentries.
Можно их хоть в Google Docs хранить и обрабатывать, но меня сам подход удивляет. Я не понимаю, в чем профит экономии на наличии СУБД, при штате из двенадцати (или из пяти) разработчиков. Да и с точки зрения разработки экономия не очевидна.
Двенадцать разработчиков на постоянной основе для одного сервиса аренды недвижимости?
Используя эту архитектуру можно почти все модули взять из сторонних решений. То есть вам придется запилить всего 2-3 модуля, а не все 5.
Даже при желании можно взять несколько сторонних сервисов и объединить в один проект, по сути так и работают различные агрегаторы. Используют API сторонних проектов как микросервисы и работают с ним, чтобы предоставить единый инструмент.
- Логи потом можно сканировать в бэкграунде. Это зависит от их приоритета.
- Предлагаю покинуть прослойку с платежным агрегатором для кредитных/дебетовых карт, например.
- Это «магические» цифры. Но в них нет ничего странного для сервиса с хорошей выручкой, который хочет быстро развиваться.
А можно поинтересоваться, чем микросервисная архитектура отличается от сервис-ориентированной архитектуры (SOA)
Недавно рассказывал и об этом тоже на ITWeekend в Киеве. Так как по теме, оставлю слайды speakerdeck.com/semirook/api-centric-web-development-with-tornado-or-the-great-refactoring-story
В последнее время всё больше плююсь от «микросервисной архитектуры» (который «частный случай soa»). Актуальные вопросы:
- Как или с помощью чего решена проблема логирования сервисов?
- Как происходит деплой?
- Версионирование компонентов. В процессе разработки может потеряться совместимость АПИ между компонентами, отслеживать какие ревизии одного компонента совместимы или не совместимы с другими сомнительное удовольствие.
Вы на практике используете эту архитектуру? Поделитесь, пожалуйста, опытом.
- В чем заключается проблема?
- Зависит от конкретного случая. Один из простых способов с минимумом администрирования — хероку.
- Делать хорошее апи: api/v1, api/v2. Почему должна потеряться совместимость?
На практике. Сразу замечу, что абсолютно все возникшие проблемы решаемы и решения известны, но на это надо потратить определённое время и усилия, особенно если не позаботиться об этом заранее.
Вначале всё начиналось именно как микросервисы, сейчас имеет тенденцию к укрупнению и ближе к стандартному SOA. Всё было хорошо, пока этих микросервисов было штук 5. Когда их количество приблизилось к десятку, оказалось, что мы объективно не справились с архитектурой. Большинство сервисов стало зависеть друг от друг друга прямо или косвенно. Например, сервис «А» может зависеть от «Б» и «В», а сервис «В» в свою очередь от «Г». Нетрудно заметить, что в этом случае, если отвалиться «Г», то вся система рискует сложиться по принципу домино. А если сбой не критичный и не проявляется сразу, то имеем фан с поиском и локализацией бага. Вот тут и всплывает, что традиционный подход, когда каждое приложение пишет в свой файл (или отдельное хранилище) тут абсолютно не подходит.
Теперь про деплой и версионирование. Сейчас деплой у нас происходит вручную на выделенный сервер. Скорей всего в итоге придём к докеру с Continuous Integration. Апи по версиям api/v1, api/v2 — хорошо для публичных АПИ. Для активно развивающихся сервисов это рискует перерасти в мешанину из устаревшего и уже не используемого кода. Сейчас стараемся сохранять обратную совместимость между компонентами без изменения версии АПИ. Но при таком подходе у нас возникла ситуация, когда надо следить в каком порядке обновлять отдельные компоненты. Например в компоненты «А» и «Б» в отдельное апи добавили одно поле, при этом «А» — посылает запросы в «Б». Если теперь вначале обновить «А», то «Б» будет сильно ругаться на неизвестное поле. Поэтому вначале обновляем «Б», а потом «А» (ситуация сильно осложняется, когда зависимостей больше). Про возможность оперативного откатывания отдельного компонента к какой либо старой версии речь даже не идёт (но и необходимости к слову не было).
В целом сейчас поддержка винегрета из отдельных сервисов (при команде из 2х-3х человек) абсолютно не проще, чем традиционный монолитный подход. А если заранее, перед внедрением микросервисов не озаботиться об необходимой инфраструктуре, то всё может сложиться очень печально.
Вначале всё начиналось именно как микросервисы, сейчас имеет тенденцию к укрупнению и ближе к стандартному SOA. Всё было хорошо, пока этих микросервисов было штук 5. Когда их количество приблизилось к десятку, оказалось, что мы объективно не справились с архитектурой. Большинство сервисов стало зависеть друг от друг друга прямо или косвенно. Например, сервис «А» может зависеть от «Б» и «В», а сервис «В» в свою очередь от «Г». Нетрудно заметить, что в этом случае, если отвалиться «Г», то вся система рискует сложиться по принципу домино. А если сбой не критичный и не проявляется сразу, то имеем фан с поиском и локализацией бага. Вот тут и всплывает, что традиционный подход, когда каждое приложение пишет в свой файл (или отдельное хранилище) тут абсолютно не подходит.
Теперь про деплой и версионирование. Сейчас деплой у нас происходит вручную на выделенный сервер. Скорей всего в итоге придём к докеру с Continuous Integration. Апи по версиям api/v1, api/v2 — хорошо для публичных АПИ. Для активно развивающихся сервисов это рискует перерасти в мешанину из устаревшего и уже не используемого кода. Сейчас стараемся сохранять обратную совместимость между компонентами без изменения версии АПИ. Но при таком подходе у нас возникла ситуация, когда надо следить в каком порядке обновлять отдельные компоненты. Например в компоненты «А» и «Б» в отдельное апи добавили одно поле, при этом «А» — посылает запросы в «Б». Если теперь вначале обновить «А», то «Б» будет сильно ругаться на неизвестное поле. Поэтому вначале обновляем «Б», а потом «А» (ситуация сильно осложняется, когда зависимостей больше). Про возможность оперативного откатывания отдельного компонента к какой либо старой версии речь даже не идёт (но и необходимости к слову не было).
В целом сейчас поддержка винегрета из отдельных сервисов (при команде из 2х-3х человек) абсолютно не проще, чем традиционный монолитный подход. А если заранее, перед внедрением микросервисов не озаботиться об необходимой инфраструктуре, то всё может сложиться очень печально.
Желательно, на мой взгляд, не делать паутину из микросервисов. В данной схеме каждый микросервис решает задачу своего родителя.
В принципе, ясно откуда появилось большинство замечаний и они вполне оправданы. В следующей статье я постараюсь рассказать как минимизировал негативные стороны. Все таки эта статья называется "Плюсы микросервисной архитектуры" :)
В принципе, ясно откуда появилось большинство замечаний и они вполне оправданы. В следующей статье я постараюсь рассказать как минимизировал негативные стороны. Все таки эта статья называется "Плюсы микросервисной архитектуры" :)
Вот право, я как раз ожидал увидеть что автор статьи тоже приведёт хоть какую-то конкретику, а не будет свои тезисы подкреплять картинками из разных фильмов.
я тут слегка вклинюсь со своими пятью рублями:
- Есть довольно много решений. У нас, например, лучше всего получилось работать с logstash
- Опять, довольно много всего. У нас лучше всего пошел Docker + Bamboo. Такая связка работает для всего вообще — от java backend'ов до фронтов, компилируемых с помощью node.js. Ну и да, без CI/CD тут никуда, руками деплоить можно рехнуться
- Это вообще отдельная тема, которая очень сильно зависит от используемого канала коммуникаций. Некоторые советуют стараться вообще избегать breaking changes и не применять versioning пока это возможно
Спасибо. Примерно к этому сейчас и идём. И как показала практика, обо всём этом лучше задумываться до внедрения микросервисов.
Микроядра наносят ответный удар? Видимо, старею, раз начинаю видеть рекрусию в технологиях.
Сам я пока приверженец монолитных больших приложений, просто разбитых внутри на модули. И в идее микросервисов меня смущает несколько моментов. Не могли бы вы просветить меня в паре вопросов?
1. При дроблении приложения на много маленьких возрастает дублирование кода. Есть код, который должен быть в каждом проиложении (те же модели ORM) и описывать их придется везде отдельно.
2. Усложняется деплой. При изменении схемы бд, мне скорее всего придется обновить не одно приложение, а все пять. Это, конечно, автоматизируется. Но сам факт.
3. Накладные расходы на общение сервисов между собой. Если взять из примера сервисы, общающиеся между собой через rest. Получается вместо прямого вызова нужного кода, мне надо будет делать http запросы и терпеть сетевые задержки.
Объясните, пожалуйста, как решаются эти проблемы?
1. При дроблении приложения на много маленьких возрастает дублирование кода. Есть код, который должен быть в каждом проиложении (те же модели ORM) и описывать их придется везде отдельно.
2. Усложняется деплой. При изменении схемы бд, мне скорее всего придется обновить не одно приложение, а все пять. Это, конечно, автоматизируется. Но сам факт.
3. Накладные расходы на общение сервисов между собой. Если взять из примера сервисы, общающиеся между собой через rest. Получается вместо прямого вызова нужного кода, мне надо будет делать http запросы и терпеть сетевые задержки.
Объясните, пожалуйста, как решаются эти проблемы?
Основной посыл по всем вопросам: микросервисы это не панацея от всех проблем и не сэкономят вам время, если выносить каждую функцию в отдельный сервис сервис. Я потом напишу статью, опираясь на реальный пример выноса функционала в микросервис. Надеюсь, что это снимет большинство вопросов.
>1. При дроблении приложения на много маленьких возрастает дублирование кода
выносим в либу
>3. Накладные расходы на общение сервисов между собой.
если это критично, не надо разделять, но в большинстве случаев это пренебрежительно мало
выносим в либу
>3. Накладные расходы на общение сервисов между собой.
если это критично, не надо разделять, но в большинстве случаев это пренебрежительно мало
> 1. При дроблении приложения на много маленьких возрастает дублирование кода. Есть код, который должен быть в каждом проиложении (те же модели ORM) и описывать их придется везде отдельно.
Как уже было сказано выделяется в подключаемые модули и либы. Это даже становится плюсом, т.к. упрощается переиспользование кода не только в рамках текущего проекта…
> 2. Усложняется деплой. При изменении схемы бд, мне скорее всего придется обновить не одно приложение, а все пять. Это, конечно, автоматизируется. Но сам факт.
Если при изменении схемы бд приходится править все приложения, то это скорее недопонимание микросервисной архитектуры. Разделение на микросервисы это просто новая ступенька модульности и инкапсуляции.
Т.е. разделение происходит по функциональностям с соответствующим разделением ответственности. В итоге получаем что у каждого сервиса своя бд наиболее подходящая под его тип данных. Или бд общая но за определенные даные отвечает только конкретный сервис.
В таком варианте изменения схемы затронут только те сервисы чьи схемы были изменены.
> 3. Накладные расходы на общение сервисов между собой. Если взять из примера сервисы, общающиеся между собой через rest. Получается вместо прямого вызова нужного кода, мне надо будет делать http запросы и терпеть сетевые задержки.
Это один из наиболее ощутимых минусов который мы ощутили на своем проект. Но мы его решили разработкой своей серверной и клиентской либы с прямым сокетным соединением.
Как уже было сказано выделяется в подключаемые модули и либы. Это даже становится плюсом, т.к. упрощается переиспользование кода не только в рамках текущего проекта…
> 2. Усложняется деплой. При изменении схемы бд, мне скорее всего придется обновить не одно приложение, а все пять. Это, конечно, автоматизируется. Но сам факт.
Если при изменении схемы бд приходится править все приложения, то это скорее недопонимание микросервисной архитектуры. Разделение на микросервисы это просто новая ступенька модульности и инкапсуляции.
Т.е. разделение происходит по функциональностям с соответствующим разделением ответственности. В итоге получаем что у каждого сервиса своя бд наиболее подходящая под его тип данных. Или бд общая но за определенные даные отвечает только конкретный сервис.
В таком варианте изменения схемы затронут только те сервисы чьи схемы были изменены.
> 3. Накладные расходы на общение сервисов между собой. Если взять из примера сервисы, общающиеся между собой через rest. Получается вместо прямого вызова нужного кода, мне надо будет делать http запросы и терпеть сетевые задержки.
Это один из наиболее ощутимых минусов который мы ощутили на своем проект. Но мы его решили разработкой своей серверной и клиентской либы с прямым сокетным соединением.
1. Знать о какой-то конкретной модели ORM должен только один микросервис (назовём его, например PersistenceManager). Если при изменении кода в одном микросервисе вам регулярно приходиться менять код в другом, то будет правильно объединить оба микросервиса в один.
2. Налицо сильное связывание в IT-архитектуре. Это не микросервисный подход. Если какому либо микросервису нужно пообщаться БД, то он должен делать это опосредованно с помощью PersistenceManager, который по своему усмотрению решает как и с какой базой работать (см. п 1).
3. HTTP позволяет легко, стандартными практиками организовать балансировку нагрузки и отказоусточивость микросервисов, а еще он работает через прокси. Можете использовать ZeroMQ если все-таки решите, что HTTP недостаточно быстр.
p.s.
Рекомендую ознакомиться с классическим трудом по интеграции приложений www.enterpriseintegrationpatterns.com
2. Налицо сильное связывание в IT-архитектуре. Это не микросервисный подход. Если какому либо микросервису нужно пообщаться БД, то он должен делать это опосредованно с помощью PersistenceManager, который по своему усмотрению решает как и с какой базой работать (см. п 1).
3. HTTP позволяет легко, стандартными практиками организовать балансировку нагрузки и отказоусточивость микросервисов, а еще он работает через прокси. Можете использовать ZeroMQ если все-таки решите, что HTTP недостаточно быстр.
p.s.
Рекомендую ознакомиться с классическим трудом по интеграции приложений www.enterpriseintegrationpatterns.com
1. Знать о какой-то конкретной модели ORM должен только один микросервис (назовём его, например PersistenceManager). Если при изменении кода в одном микросервисе вам регулярно приходиться менять код в другом, то будет правильно объединить оба микросервиса в один.
Расскажите, пожалуйста, подробнее про это. Вы предлагаете сделать один микросервис для всего приложения, который будет заниматься persistence'ом?
Знать о какой-то конкретной модели ORM
Иначе говоря, объекты одного класса не должны персиститься более чем одним сервисом/реализацией.
Сервисов, занимающихся ORM может быть сколь угодно много.
Polyglot Persistence опять же никто не отменял.
Допустим у нас есть микросервис, который отвечает за менеджмент пользователей и сервис, который отвечает за каталог товаров. Обычный CRUD, ничего сверхестественного.
По Вашей логике, надо сделать ещё сервисы, которые будут отвечать за работу с БД, на каждый микросервис? Итого у нас получится такой список сервисов:
Правильно ли я Вас понял?
По Вашей логике, надо сделать ещё сервисы, которые будут отвечать за работу с БД, на каждый микросервис? Итого у нас получится такой список сервисов:
- Пользователи
- ORM Пользователи
- Каталог
- ORM Каталог
Правильно ли я Вас понял?
Я говорил о том, что не стоит использовать разные сервисы для управления ORM одного типа объектов. Это высказывание не запрещает использование одного микросервиса для нескольких ORM.
Например такой кейс — регистрация пользователя в интернет-банке:
— можно зарегистрироваться в офисе;
— можно зарегистрироваться через интернет;
В обоих случаях один и тот же сервис должен выполнить запись о пользователе в какую-то базу (LDAP каталог, SQL, NoSQL, ?). Хотя и получит запрос из разных источников.
Если разбирать Ваш пример, то я бы сгруппировал сервисы попарно:
В этом есть смысл если пользователи лежат в LDAP, а товары, например в MongoDB.
Но я не знаю всех деталей вашего проекта и по этому строю свои предположения со многими допущениями.
Например такой кейс — регистрация пользователя в интернет-банке:
— можно зарегистрироваться в офисе;
— можно зарегистрироваться через интернет;
В обоих случаях один и тот же сервис должен выполнить запись о пользователе в какую-то базу (LDAP каталог, SQL, NoSQL, ?). Хотя и получит запрос из разных источников.
Если разбирать Ваш пример, то я бы сгруппировал сервисы попарно:
- Пользователи (логика) + ORM Пользователи
- Каталог (логика) + ORM Каталог
В этом есть смысл если пользователи лежат в LDAP, а товары, например в MongoDB.
Но я не знаю всех деталей вашего проекта и по этому строю свои предположения со многими допущениями.
Немного прокомментирую не по теме, а по оформлению. Вот эта фразу: «Незаменимых нет» нужно иллюстрировать не той картинкой, что у вас, а этими:
В России это выражение известно как фраза И. В. Сталина, хотя в таком виде нигде в его речах или сочинениях она не встречается… Имея в виду некоторых высших партийных и советских чиновников, он сказал: «Эти зазнавшиеся вельможи думают, что они незаменимы и что они могут безнаказанно нарушать решения руководящих органов. Их надо без колебаний снимать с руководящих постов, невзирая на их заслуги в прошлом».
Очень много сказано о плюсах, но минусы же тоже имеются. Почему о них ни слова?
Можете рассказать на какие грабли вы наткнулись и как решали?
Можете рассказать на какие грабли вы наткнулись и как решали?
В третьей публикации. Будет еще вторая по микросервисам (практическая), тоже в положительном ключе.
Отлично! Тогда с нетерпением жду продолжения. Если надо будет материала подкинуть, обращайтесь. Могу еще своего опыта добавить. У нас проект специфичный: hiload, bigdata и все такое…
Вот: habrahabr.ru/post/261267 :)
Если у вас найдется время, то расскажите о проекте в личном сообщении.
Если у вас найдется время, то расскажите о проекте в личном сообщении.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Плюсы микросервисной архитектуры