asman.malikov_ EN

Архитектурное решение · fintech

Геораспределённый биллинг на Temporal SAGA

Бэкенд / Платформа GoTemporalgRPCKafkaNATSPostgreSQL

callback ─► core · Temporal SAGA ──task queue──► region wallet
  find/create → parse → FX (replay) → deposit → status → event
  любой сбой ⇒ LIFO-компенсации · Kafka держит колбэки durable

Проблема

Распределённой платёжно-биллинговой платформе нужно было обрабатывать денежные депозиты по регионам с гарантией exactly-once — переживая отказ региона, сетевые разрывы и дубли колбэков провайдеров — без хрупкого самодельного координатора и без two-phase commit.

Подход

Смоделировал депозит как Temporal SAGA — шестишаговый workflow с LIFO-компенсациями. Операции с кошельком выполняются в регионе, оркестрация остаётся в core; запросы роутятся по региону через task queues и gRPC fire-and-forget, а транспорт core↔region спроектирован и сравнён в двух вариантах — региональный Temporal-воркер по WAN и NATS request/reply. У каждой activity свой ключ идемпотентности, FX-курс фиксируется на первом исполнении и реплеится из event history на ретраях, а колбэки провайдеров приходят через Kafka — доставка переживает даунтайм Temporal.

Результат

Межрегиональные депозиты, эффективно ровно один раз — сбойный шаг запускает компенсации, зависший workflow ограничен таймаутом, дубли колбэков дедупятся по workflow ID, а недоступный регион деградирует безопасно с алертами, не теряя и не задваивая деньги.

Доказательства

Описано в истории работы (Korvax, 2022–настоящее время). Трейд-оффы дизайна — сравнение транспортов core↔region, семантика компенсаций и матрица отказов — разбираемы в звонке.

Доступно для: приватный разбор

Координатор — это сам workflow: Temporal сохраняет каждый шаг, поэтому после падения исполнение продолжается с последней завершённой activity, а не переигрывает side-effects. Идемпотентность на каждой activity плюс LIFO-компенсации — вот что делает «зачислить депозит ровно один раз» правдой между регионами, даже когда колбэки at-least-once, а целый регион может исчезнуть на середине.

AI-читаемая запись (Markdown) · ← Назад к библиотеке