LINUX.ORG.RU

Микросервисная архитектура на python

 , ,


3

4

Нашел пример реализации сабжа на flask - https://github.com/umermansoor/microservices
Сразу же меня смутило одно, каждый сервис поднимается на отдельном порту - 5000, 5001, 5002....
Собственно это пугает, не так давно перешел с php на python, хочу реализовать micro service arch приложение, но куда копать лучше пока не знаю, смотрел еще на nameko, кто с ним работал? Что посоветуете?

Копай в сторону описания микросервисной архитектуры.

cnupm
()

Советую исходить из ТЗ и не страдать культом самолётников.

Goury ★★★★★
()

Сразу же меня смутило одно, каждый сервис поднимается на отдельном порту - 5000, 5001, 5002....

А как иначе-то?

Kilte ★★★★★
()

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

Dred ★★★★★
()
Ответ на: комментарий от Dred

а если я не ошибаюсь в nameko юзается rpc, такой же метод занимания портов или что то другое там?

noname_user ★★★
() автор топика

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

А как иначе? Два сервиса на одной машине не могут слушать на одном порту. Вообще, с микросервисами забудь о фиксированных адресах и портах. Копай в сторону service discovery. Можешь посмотреть какой-нить consul, например.

true_admin ★★★★★
()

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

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

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

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

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

Но это когда ты реальное приложение пишешь.

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

alpha ★★★★★
()
Ответ на: комментарий от alpha

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

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

Deleted
()

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

anonymous
()
Ответ на: комментарий от true_admin

А у меня возникло несколько вопросов в общей реализации из примера выше — flask же умеет работать с несколькими приложениями одновременно, зачем разные порты для каждого сервиса? Даже если разные порты для каждого сервиса, gunicorn разве не может слушать их всех?

conformist ★★★
()

Что посоветуете?

Android Binder. Зачем вообще 100500 сервисам взаимодействовать через TCP где ты проходишь по всему TCP/IP стэку чтобы отправить сообщение? Если уж чешется, то хотя бы unix сокеты посмотри.

xpahos ★★★★★
()

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

CaptainFarrell
()
Ответ на: комментарий от conformist

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

Ты не понял суть микросервисов :). Суть в том чтобы размазать приложение по кластеру машин, предоставлять high-availability и масштабирование.

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

Или, хуже, если упадёт flask (или сервер сломается) то весь твой сервис станет недоступен. Кстати, поэтому лучше делать так чтобы каждый микросервис был запущен в нескольких экземплярах на разных машинах. Лучше даже в разных датацентрах.

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

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Вот теперь понял, спасибо. А я сразу взглянул в сторону Blueprint.

conformist ★★★
()
Ответ на: комментарий от Deleted

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

alpha ★★★★★
()
Ответ на: комментарий от alpha

разделил сервисы не в том месте и создал кашу из зависимостей.

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

Deleted
()
Ответ на: комментарий от Deleted

это вопрос рефакторинга, он решаем одним архитектором

ты как-то очень лихо одним махом решил все проблемы разработки

alpha ★★★★★
()
Ответ на: комментарий от noname_user

не фокусируйся на фреймворке

к тому времени как тебе надо будет писать production-сервис, будет ещё 18 новых языков программирования и 25 фреймворков в каждом

микросервисы - это принцип, реализуй на чем угодно, принцип тот же

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

alpha ★★★★★
()
Ответ на: комментарий от Deleted

ну практически любая проблема разработки сводится в итоге к «вопросу рефакторинга», который ты решил

alpha ★★★★★
()
Ответ на: комментарий от alpha

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

Deleted
()
Ответ на: комментарий от Deleted

это не ко мне вопрос

я не знаю почему у тебя «переписывать логику взаимодействия с одним модулем на асинхронную» - это не рефакторинг

alpha ★★★★★
()
Ответ на: комментарий от alpha

наверное потому что ты путаешь рефакторинг и полное переписывание почти с нуля 8)

Deleted
()

Один порт может занимать несколько сервисов (фактически это будет один расширенный сервис). На практике это не требуется, но говорить что это невозможно некорректно. Приведу пример. Мы имеем самописный два в одном сервер: http и irc.
Когда подключается клиент смотрим первую отправленную строку. Если это что-то наподобие «GET /index.html HTTP/1.1» - работаем с клиентом как http-сервер. Если сообщение начинается с двоеточия - пытаемся парсить как сообщение от irc клиента.

anonymous
()
Ответ на: комментарий от Deleted

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

Это почему? Или я чего-то не понял из контекста?

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

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

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

А так, синхронный код можно масштабировать тредами.

и пока упавший сервис отдуплится наш «микросервис» успеет выжрать лимит потоков 8) создавая новые на каждый тутже зависающий запрос

Deleted
()

Да хорош уже думать как правильно, возьми да напиши, а потом в процессе придешь к тому как правильно.

ggrn ★★★★★
()
Ответ на: комментарий от Deleted

Wat? :) Ограничение кол-ва requests in fly это must have для любого сервиса, как синхронного так и асинхронного. Я уже писал про это выше. Ты не хочешь открыть дохренища одновременных транзакций в одной БД, даже если твой супер-асинхронный код так может. Тут или БД/сторадж раком встанет, или какие-нить дескрипторы/память/семафоры/whatever выжрется.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Wat? :) Ограничение кол-ва requests in fly это must have для любого сервиса,

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

посмотри сколько херни и все потому что ты «масштабируешь потоками».

Deleted
()
Ответ на: комментарий от Deleted

Слишком большой concurrency зло. Почему я уже объяснил. Да, если сервис перегружен то надо возвращать ошибку. Это microservices 101. Посмотри «Limit Everything» и «Connection Pools» вот здесь, например: http://www.vinaysahni.com/best-practices-for-building-a-microservice-architec... . Особое внимание на «remember to fail fast», «Short Timeouts» и «Circuit Breakers».

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

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Да, если сервис перегружен то надо возвращать ошибку.

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

Думай что ты сделал не так.

Deleted
()
Ответ на: комментарий от Deleted

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

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

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

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

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

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

Ты вообще трезв? Или ты так извращенно стебешься надо мной?

Deleted
()

хочу реализовать micro service arch приложение

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

outtaspace ★★★
()
Ответ на: комментарий от Deleted

Хм, я хотел то же самое спросить у тебя.

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

Допустим, у тебя есть сервер для видеокодирования и тебе на вход 1000 видосов подали для перекодирования. Сколько процессов ffmpeg ты запустишь? 1000?

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Допустим, у тебя есть сервер для видеокодирования и тебе на вход 1000 видосов подали для перекодирования. Сколько процессов ffmpeg ты запустишь? 1000?

Вот тут: Микросервисная архитектура на python (комментарий) - я написал про очереди, нетрудно догадаться, что я про них в курсе.

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

Напоминаю: про очереди я в курсе.

Deleted
()
Ответ на: комментарий от Deleted

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

Я это понимаю как «очереди это зло т.к. могут переполниться». Что типа в асинхронном коде очереди не нужны. Всё правильно?

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

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

Синхронный код приведет к тому что у тебя кончится лимит потоков, потом заполнится очередь - и только после этого код отправляющий сообщения (и то в очередь) узнает что там что-то не так. Вотчдог скажет - «микросервис испортился» и перезапустит его, ведь это нормально для микросервисов! И вся пачка обрабатываемых сообщений похерится.

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

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

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

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

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

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

абстрагируют отправителя от проблем приемника

Либо крестик, либо штаны. Ты уж определись чего ты хочешь: сервис который будет молча продолжать принимать запросы даже когда загружен на 100% или же отдавать ошибку и, скажем, сообщать load balancer-у что нужно принимать меры.

Я ещё раз повторю главную мысль: многие ресурсы не скейлятся по кол-ву одновременных запросов: базы данных, файловые системы, «тяжёлая» обработка данных. Как ты не крутись ты не можешь открыть тыщу транзакций в одной базе. И в таких случаях надо ограничивать и сериализовывать запросы. А значит нужно ограничить одновременное кол-во потоков выполнения (будь то треды или гринлеты).

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

Но на жирном бэкенде толку от твоих гринлетов? Чем они помогут, скажем, закодировать видосы? Тут не имеет смысла пускать больше обработчиков чем (плюс-минус) кол-во ядер в системе (здравствуйте очереди заданий). В БД ты не захочешь иметь тыщи одновременных соединений и кучу висящих транзакций. Многие shared-сервисы ограничивают кол-во одновременных запросов с одного IP по понятным причинам. Ты с этим согласен?

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

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

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

Deleted
()

Питон тут побоку, это всеголишь язык. Пишеш микросервисы на чем угодно, но слушаеш не на tcp, а по uds. Оверхед ниже, порты не заняты. А перед всем этим ставиш нгинкс и в нем уже маршрутизацию хоть как делаеш до этих сервисов. Припрет - выносиш часть сервисов на другую машину, там свой нгинкс. При необходимости балансировку и роутинг между нодами темже нгинксом. Если хочется савсем странного - пилиш свой «нгинкс» на фласке+гевент. Для тестирования бывает удобнее.

Тебе ведь это для обучения-потыкать, надеюсь?

genryRar ★★
()
Ответ на: комментарий от genryRar

Для понимания построения архитектуры, думаю, самое оно, thx

noname_user ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.