читающие?
Есть 2 го сервиса, которые вычитывают outbox табличку и создают ивенты. Но т.к. реплики 2, то каждая запись будет вычитываться 2 раза. Какие есть способы это решить?
Делаете поле статус, при вычитывании ставите его в PROCESSING, после отправки ставите в DONE, вычитываете только записи в статусе NEW
Читать в одну реплику.
звучит на самом деле круто) надо попробовать, спасибо
их всегда больше 1й для отказоустойчивости
еще можете тупо ставить advisory lock, вычитывать все что надо, потом закрывать транзаху и отдавать этот лок
Звучит не круто. Во-первых, без локов эта история не будет работать. Во-вторых, две реплики создают беспорядок в событиях, а это часто бывает важно.
ну естественно на локах
Чем две реплики гарантируют отказустойчивость? Если база лежит, лежат обе реплики. Если кафка лежит, лежат обе реплики. Для такой задачи одной реплики хватит. Вам из базы в кафку положить. Без локов на базе. Плюс остается оригинальный порядок событий.
тем, что если 1 реплика лежит, вторая не лежит они в разных дц
Таблица тоже в разных дц? А вообще, можно взять готовый cdc типа дебезиума.
в одном. Но реплики сервисов всегда две поднимаются
с этого и стоило начинать, что просто несолько инстансов приложения. тогда какой нибудь Leader election
так вроде и написал, что 2 реплики есть
leader election - будет одна реплика работать. А в идеале две
Вы для чего оутбукс берете?
клиент делает запрос в сервис1, если валидация прошла, отдаю 200. Дальше надо из сервиса1 сделать запрос в сервис2 и сервис3, которые могут не работать в данный момент, например, в течении суток. (Потом поднимуться). И вот сервис1 кладет в аутбокс, потом сам же вычитывает и шлет в 2 других сервиса
Хорошо, если заменить базу на очередь, то как обеспечить транзакционность? Пришел запрос отправил в очередь1 и перед отправкой в очередь2 сервис упал - косяк.
Если использовать кролик, то вы отправляете в обменник, а не очередь, к обменнику могут быть прикреплены две очереди. Если использовать кафку, вы отправляете в один топик, который читают разные консьюмер-группы.
А чем решение с локами не вариант?
Может быть требование например по реплике на ДЦ. База тоже может состоять из не одной реплики
вариант. Пока так и сделаю
Важнее задачу в джире закрыть или использовать правильный инструмент под задачу?
Для отказоустойчивости стейтфул приложений, обычно все равно только одна реплика активная. Даже если запущены две. Вторая в пассивном режиме
а почему подумал, что это стейтфулл?
Ну эта табличка разве не является в каком-то смысле стейтом? Можно сделать балансер который будет из нее читать в одну реплику и распределять по воркерам. Но в конечном итоге, чтобы не было дублирования обработки ивентов, где то должен быть один процесс который этим распределением занимается. Тогда воркеры будут стейтлесс, а балансер все равно стейтфул, как минимум он хранит указатель на последний обработанный ивент.
ну база то это всегда стейт. Суть в том, чтобы сервисы сделать стейтлес. В какой-то мере я это и хотел
Если хочется для ускорения именно обрабатывать) можно еще каждой реплике назначать номер от 0 до N и каждая реплика должна обрабатывать ивенты с ID остатком деления на номер реплики будет 0. Но это лишь ускорит процесс обработки. Для отказоустойчивости все равно будет подстраховочная реплика для каждого номера, которая подхватит работу, если лидер упадет
зачем, если можно просто через лок брать пачки?
Можно и через лок брать
В конечном итоге нужно добиться exactly once или at least once delivery?
at least once не добиться. Тут потребность не в какой-то семантике, а чтобы 2 реплики не делали ту же самую работу
Обсуждают сегодня