Добрый день, подскажите пожалуйста бест практис, Задача в том чтобы реализовать

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

вопрос в первую очередь, как реализовать синхронное взаимодействие в виде request/reply ?

Думали сделать такой вариант: веб клиент генерит corellationId и выполняет запрос к бэку например createBook,
далее логика такая
1. бакнед подписывается на топик кафка book-created спомощью KafkaStreams делает filter по key=correlationId
2. бакнед отпарвляет команду CreateBookCmd в топик кафка book-create и среди прочего передает correlationId
3. далее какой-то консьюмер обрабатывает команду из топика book-create, создает Book и генерит BookCreatedEvent в топик book-created
4. бакенд получате событие из топика book-created с нужным corellationId и затем отдает ответ на вебклиента.

в таком сценарии получается что на каждый запрос вебклиента создается новый короткоживущий экземпляр KafkaStreams и вызывается start , stop
вопрос насколько ресурсоемко создание экземпляров KafkaStreams на каждый запрос от вебклиента?
как я понимаю такое решение аналогично созданию консьюмера для топика book-created с последующим чтением всех событий и отбрасыванию с несоотвсвующими corellationId.
Соответсвенно вопрос насколько ресурсоемко создание коньюмера на каждый запрос от вебклиента?

Может быть есть более правильные паттрены (что бы уйти от request/reply на фронте)?

19 ответов

7 просмотров

Клиент же реактивный, подозреваю? И тогда никакой синхронный http ему и не нужен, проще request получить через http (и там, конечно, просто rest level 1), а ответ получить через подписку на websockets, склейку и сам клиент может сделать. Это будет гораздо масштабируемее и проще в реализации в конечном итоге. Единственное - нужно будет как-то обеспечивать надежные очереди для websockets, но для этого есть вполне себе набор внешних решений

Phil Delgyado
Клиент же реактивный, подозреваю? И тогда никакой...

а в чем проблема в очередях для вебсокетов, если из кафки читаем и сразу пушаем в сокет?

Nick
а в чем проблема в очередях для вебсокетов, если и...

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

Phil Delgyado
Тебе нужно нормально отработать переподключение со...

я так понимаю, что если у нас при переподключении заново запрашивается состоние для клиента и оно собирается, то по сути это неважно

Nick
я так понимаю, что если у нас при переподключении ...

Это дорого: при каждом въезде в туннель весь стейт перезапрашивать

Phil Delgyado
Это дорого: при каждом въезде в туннель весь стейт...

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

а сколько у вас будет таких клиентов в штуках?

Sergey-Sokolov Автор вопроса
Phil Delgyado
Клиент же реактивный, подозреваю? И тогда никакой...

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

Sergey Sokolov
Тут вопрос , как в определенную websocket сессию о...

Это умеют делать внешние инструменты (

Sergey-Sokolov Автор вопроса
Nikolay
а сколько у вас будет таких клиентов в штуках?

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

Sergey Sokolov
Если по одновременным подключениям, то не думаю чт...

не совсем понятно. Если основная задача - реализовать совместное редактирование , то можно взять CRDT?

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

Sergey-Sokolov Автор вопроса
Nikolay
не совсем понятно. Если основная задача - реализов...

Ну это не совсем основная задача,это один из юзкейзов, да CRDT тоже интересно, но пока не рассматривали (вот интересный фреймворк на эту тему https://cloudstate.io). С одной стороны хочется не оверинжинирить, а с другой понятно, что без работы с событиями сложно что то сделать.

Sergey-Sokolov Автор вопроса
Ilgiz
Зачем создавать короткоживущие клиенты, почему нел...

Да, в эту сторону тоже надо будет посмотреть, действиетльно если есть мапа correlationId->session , то можно читать полностью топик и в нужную сессию отправлять событие. Главное только держать в актуальном состоянии эту мапу.

Вряд ли бестпрактис уже сформировались. И много факторов есть, которые влияют на выбор решения. Добавлю свои 5 копеек. 1. Зачем столько разных топиков? Можно реквест-респонсы складывать в один, тогда сообщения с одинаковым ключом будут в одном партишне и упорядочены по времени. Консьюмеры будут фильтровать по ключу/хидерам и брать то, что нужно им, это достаточно дешево. В блоге конфлюент есть несколько постов на эту тему. 2. В чем профит создавать короткоживущий стрим? Выглядит как усложнение в описанном кейсе. Если все происходит в рамках одного реквест-респонса с фронта, то можно обойтись консьюмером из топика/партишна и хоть в памяти сервиса держать мапу с correlationId реквестов, так как шарить ее между несколькими инстансами смысла особого нет. Рядом можно список держать с отсортированными по времени реквестами, который пригодится для чистки мапы. Вариант плох тем, что поток должен будет простаивать и проверять мапу в ожидании ответа из топика, чтобы потом его отдать на фронт. Либо нужно менять схему реквест-респонс, и, например, процесс запускать с фронта на одном эндпоинте, а потом результат спрашивать на другом, опрашивая в цикле сервис, либо вебсокеты, как уже писали выше. Но тогда уже нужно шарить данные между инстансами и использовать бд или редис какой-нибудь.

Gosha
Вряд ли бестпрактис уже сформировались. И много фа...

> тогда сообщения с одинаковым ключом будут в одном партишне и упорядочены по времени так здесь нет ни какого профита от сохранения порядка, а вот skip'апть сообщения не предназначенные для обработки consum'ером respon'зов может и не так дорого, но и можно этого избежать > Вариант плох тем, что поток должен будет простаивать и проверять мапу в ожидании ответа из топика ну а зачем так плохо делать, если можно сделать хорошо ) не надо ждать в потоке, пока придет response, можно вернуть его в пулл и поставить какой-нибудь асинхронный lock и уже реактивно его снять, когда придет response. другой вопрос, что там надо будет учитывать всякие тайматы http-соединения, но это уже особенности реализации

Artem Nenashev
> тогда сообщения с одинаковым ключом будут в одно...

1. Зависит от того, как дальше планируется данные использовать. Еще при отладке/поиске проблем без доп инструментов пару реквест-респонс удобнее смотреть в одном топике и на одном партишне. В экстремальных случаях с тысячами топиков такое кол-во может аффектить на перформанс. В общем, как лучше раскидать данные по топикам это отдельная большая тема. 2. Скорее всего, даже в каком-нибудь реактивном фреймворке можно посмотреть решение и сделать по аналогии. Но задачка нетривиальная для обычного крудописателя. И еще вопрос, стоит ли оно того.

Sergey-Sokolov Автор вопроса
Gosha
Вряд ли бестпрактис уже сформировались. И много фа...

Понравилось вот такое решение https://medium.com/codable/an-opinionated-approach-to-developing-event-driven-microservice-applications-with-kafka-and-8018122e33a9

Похожие вопросы

Обсуждают сегодня

Всем привет. Подскажите, почему не меняется значение поля при переключении сайта?
Alexander Peterikov
11
Можно ли загрузить скрипт py в бота чтобы он работал по нему? как это сделать?
huskadam #RCC Фанат? @hitlerpvp
13
'frakturBold' => ['𝖆', '𝖇', '𝖈', '𝖉', '𝖊', '𝖋', '𝖌', '𝖍', '𝖎', '𝖏', '𝖐', '𝖑', '𝖒', '𝖓', '𝖔', '𝖕', '𝖖', '𝖗', '𝖘', '𝖙', '𝖚', '𝖛', '𝖜', '𝖝', '𝖞', '𝖟', '𝕬', '𝕭', '𝕮', '𝕯'...
Roma
4
Добрый день, не подскажите, если в OC-V3 поменять страндартную директорию /storage/ на /storage2/ - не будет сильно много проблем ?
Max Dubovsky
32
Ребят, а за скок можно впарить анон чат с апишкой и веб админкой ?
Eugene Неелов
15
Цвет аватарки с буквой же зависит от айди? Как может быть такое, что этот цвет поменялся?
Lencore
2
Приветствую друзья, подскажите сколько в среднем стоит на данный момент создать тг бота который будет как магазин? Показывать ассортименты доставлять заказы и тд? Все по станд...
Eugene
3
@dblackCat Привет. Это же твой плагин? https://octobercms.com/plugin/catdesign-productbundle
Alexey Yakimov
5
Добрый день! Кто-нибудь знает как подключить твиг в контроллеры плагина?
Николай Афанасенко
5
Ты просто гитлеровскую эстетику плохо понимаешь. Он же всё под Цезаря делал. А это как бы запрещённый приём в политике. Пиджаки они зачем все носят? Чтобы показать что они тип...
Ivan Kropotkin
4
Карта сайта