DDD EVENT-SOURCE CQRS SAGA COREOGRAFIA ON RABBITMQ STREAM buzz bingo!

gabriel mancini
sysmap-labs
Published in
5 min readSep 8, 2022

Disclaimer

Este eh o primeiro de uma serie de artigos que visam, experimentar o novo plugin de stream do rabbitmq, porem com uma abordagem de implementacao de saga e devido a profundidade teorica preciso definir alguns temas tecnicos dentro do contexto dos artigos

introducao do problema

Em um software podemos agrupar dados de varias maneira, e o que sai de um “mvp” de “DDD” normalmente eh algo do tipo:

  • core: [Produto/Servico] …(DDD entities with details of the domain core)
  • suporte: [Cliente] [Fornecedor] …(users types)
  • generic: [Orders] [Payments] [Delivery]

tudo embrulado em um “big ball of mud”. afinal eh um MVP certo?

ok, tudo certo. Mas hj eh um novo dia e, esse mvp vai ser a nossa “producao” de hj em diante.

ahh.. ok, soh um momento… claque-claque ….BUM!

ok precisamos de um novo dev.

e se?

Caso haja indisponibilidade de qualquer um dos servicos externos tipo (email, pagamento, delivery…), havera indisponibilidade do sistema, e pior, so saberemos no momento em que os telefones nao pararem de tocar. E mais, como poderiamos ter ciclos de deploy distintos dentro de cada parte, ou ainda, eh possivel plugar novos servicos ja atendendo os antigos clientes, notificacoes, diferentes loads, etc…?

Pq faz sentido fazer comecar por um MVP

eh rapido, relativamente barato, e apos o discovery e a modelagem do DDD ta tudo na mao, mas tudo foi construido com o mindset de “Vamos fazer funcionar” (MVP). A prova de conceito do modelo e “meio” q “funciona”

Mas, porem, entretando, todavia a vida continua e no dia seguinte precisamos desconstruir essa “big ball of mud”.

how?

Estrategia

fluxo da transacao

DDD


Plataforma "X"
Bouded Context (Ubiquous language) Users (facade) Models User Sales (facade) Models (User) Customer |> Address Item Order Payment Core (Inventory) Delivery Aggregates Order state customer model basket list<item> total scalar decimal status enum (Open | Close | Fail | Success) commands (imperative and what) events (what on past) Create Order Order Created Add Item to Basket Order Updated Remove Item to Basket Order Updated Update Order Order Updated Succeeded Failed Payment state order model customer model amount scalar decimal status enum (New | Validated | Processing | Processed | Fail) commands events Process Payment Payment Created Validate Payment Payment Validated Process Payment Payment Processed Failed Inventory state order model customer model status enum (Validating | Validated | Pulled | Fail) commands events Check Inventory Inventory Validated Pull Inventory Inventory Pulled Failed Delivery state order model customer model status enum (Delivering | Fail | Success) commands events Send Delivery Succeeded Failed

EVENT-SOURCE eh um tipo de Event Driven Architecture

the big immutable log

2022.03.01:00.00.00.0000z Order Created           balance:  0   |2022.03.02:00.00.00.0000z Item added to Order     win:      200 |2022.03.02:00.00.00.0001z Payment Placed          cred:    1000 |  2022.03.03:00.00.00.0000z Item added to Order     win:      400 |2022.03.03:00.00.00.0001z Item removed from Order loss:    -200 V

create/read : yes

update/delete : no

CQRS escalar leituras e escritas de forma independente

vindo de

CQS - Command Query Separation

// Commands: Writeuser.login() // Change State, does not return state// Queries: Readuser.isLoggerIn() // Does not change state, return state

CQRS = CQS no nivel de application

Command Query Responsability Seggregation

tradicional Application

(Mutable state)

cqrs Application

(incompatible data models (ca’nt use 5NF) + Mutable state)

cqrs + es Application

a single flow of data

CAP

Consistency Avaliability Partition

CA vs CP vs AP 
CA = can't be distributed
CP = Consistency but can be indisponible
AP = Avaliable but can be inconsistent in a small amount of time
CP cases: (hard realtime)
Governo
Saude
Seguranca
AP cases: (soft realtime)
Financeiro (bancos/cartoes de credito ...)
Telecom
e-commerce
Redes Sociais

especializacoes sao: Event Streaming vs Event Routing

SAGA

Um passo alem do EventSource com a capacidade de transacoes distribuidas. O padrão de arquitetura Saga permite que os arquitetos definam exatamente como uma transação deve funcionar. Porem sua implementacao ja falou algumas vezes... Aqui algumas lapides do Cemiterio das transacoes distribuidas vendidas como panaceia - CORBA - EJB2.1 
- EJB3
- COM+
- DCOM
- ...

Trasacoes Distribuidas podem ser “mitigadas” em caso de rollback com o SAGA pattern

  • Cada servico eh responsavel por “fazer” e “contrafazer”.
  • O desfazer precisa ser idempotente
T1, T2, T3...TN (success) 
T1, T2, F, C2, C1 (fail)

Orquestration vs Coreography

Orquestration: uma entidade externa controla o fluxo das msgs e eh responsavel pelo rollback

  • Pros:
simplifica a implementacao dos servicos 
simplifica o fluxo de undo
implementado com reducer
split process
  • Cons:
single point of failure 
entidade oculta do negocio
implementado com commands e nao eventos
join process

Coreografy: Os proprios servicos implementam o “do” e “undo” e verificam as msgs de erro

Pros e Cons opositores a orquestracao

A case for protobuf vs json

Para o caso do artigo, o protobuf ja vem com as tipagens nativas o que diminui o overhead de criar isso em jsonschema ou outros tipos

protobuf:

Pros 
- Magnitudes menor (sizeing) que Json
- Tipagem nativa tanto pra tipo como pra msg e ainda pra services (type casting)
Cons
- Binario, nao lido por humanos
- Impopular (em relacao ao json)

json:

Pros 
- Texto, Human Readable
- Popularidade
Cons
- Necessaria a utilizacao de JSON Schema ou algo do genero
- Serializacao Lenta

Usar o novo plugin do Rabbitmq Stream como uma alternativa ao Kafka.

Usar o protobuf como uma alternativa ao AVRO

Desenvolver os microservicos em nodejs e reservamos 4 chanais de comunicacao por microservico

Anatomy of a Lifecycle

No proximo artigo vamos implementar os microservicos e executar usando o docker-compose

--

--