⚡Entity state transfer
В микросервисной архитектуре часто возникает задача, чтобы один микросервис реагировал на изменения сущностей другого микросервиса. Для примера возьмем следующую задачу:
1. Есть ticket service, хранящий обращения пользователей. Тикет задается тремя полями: id — идентификатор обращения, status — текущий статус OPEN / CLOSED и assignee — текущий оператор, обрабатыващий тикет
2. Есть chat service, который связывает обращения пользователей с оператором, ботом и т.д. Он должен как-то реагировать на изменения тикета
Возникает вопрос — как передавать изменения стейта
1. Синхронный подход
При изменении тикета ticket service синхронно дергает ручку в chat service, которая обработает изменения. Самый простой в реализации подход, но возникает проблема с high-coupling — в случае недоступности chat service будет недоступен и ticket service. Однако они должны уметь существовать в отдельности друг от друга, и доступность одного сервиса не должна влиять на доступность другого
2.1. Асинхронный подход: id
Ticket service отправляет эвент, говорящий, что “что-то изменилось у тикета с определенным id”. Далее chat service, получая этот эвент, синхронно идет в ticket service и получает актуальный стейт. Такой подход хорош тем, что он охватывает сразу все изменения тикета, а также позволяет особо не думать про порядок эвентов — тк мы все равно сами ходим за актуальным стейтом. Из минусов — повышенная нагрузка на чтение на ticket service
2.2. Асинхронный подход: only change
Ticket service отправляет эвент, говорящий, что конкретно изменилось. Например status: OPEN -> CLOSED. Такой подход хорош тем, что отправляются лишь минимальный необходимый набор данных, но здесь уже нужно думать про порядок эвентов — потому что может быть важно обрабатывать изменения status и изменения assignee ровно в том порядке, в котором они произошли в тикетной системе
2.3. Асинхронный подход: snapshot
Ticket service отправляет эвент со снапшотом текущего тикета. Из плюсов — не нужно синхронно ходить за стейтом тикета, он уже полностью есть в эвенте; особо не нужно думать про порядок — можно хранить timestamp последнего обработанного снапшота, и если приходит более ранний, то просто игнорируем. Из минусов — хранение в брокере большего объема информации
В микросервисной архитектуре часто возникает задача, чтобы один микросервис реагировал на изменения сущностей другого микросервиса. Для примера возьмем следующую задачу:
1. Есть ticket service, хранящий обращения пользователей. Тикет задается тремя полями: id — идентификатор обращения, status — текущий статус OPEN / CLOSED и assignee — текущий оператор, обрабатыващий тикет
{
“id”: 123,
“status”: “OPEN”,
“assignee”: null
}
2. Есть chat service, который связывает обращения пользователей с оператором, ботом и т.д. Он должен как-то реагировать на изменения тикета
Возникает вопрос — как передавать изменения стейта
1. Синхронный подход
При изменении тикета ticket service синхронно дергает ручку в chat service, которая обработает изменения. Самый простой в реализации подход, но возникает проблема с high-coupling — в случае недоступности chat service будет недоступен и ticket service. Однако они должны уметь существовать в отдельности друг от друга, и доступность одного сервиса не должна влиять на доступность другого
2.1. Асинхронный подход: id
{
“id”: 123
}
Ticket service отправляет эвент, говорящий, что “что-то изменилось у тикета с определенным id”. Далее chat service, получая этот эвент, синхронно идет в ticket service и получает актуальный стейт. Такой подход хорош тем, что он охватывает сразу все изменения тикета, а также позволяет особо не думать про порядок эвентов — тк мы все равно сами ходим за актуальным стейтом. Из минусов — повышенная нагрузка на чтение на ticket service
2.2. Асинхронный подход: only change
{
“id”: 123,
“status”: {
“old”: “OPEN”,
“new”: “CLOSED”
}
}
Ticket service отправляет эвент, говорящий, что конкретно изменилось. Например status: OPEN -> CLOSED. Такой подход хорош тем, что отправляются лишь минимальный необходимый набор данных, но здесь уже нужно думать про порядок эвентов — потому что может быть важно обрабатывать изменения status и изменения assignee ровно в том порядке, в котором они произошли в тикетной системе
2.3. Асинхронный подход: snapshot
{
“id”: 123”,
“status”: “CLOSED”,
“assignee”: “operator_login”,
“snapshotTimestamp”: “2024-11-12T13:14:15Z”
}
Ticket service отправляет эвент со снапшотом текущего тикета. Из плюсов — не нужно синхронно ходить за стейтом тикета, он уже полностью есть в эвенте; особо не нужно думать про порядок — можно хранить timestamp последнего обработанного снапшота, и если приходит более ранний, то просто игнорируем. Из минусов — хранение в брокере большего объема информации