Staged Event Driven Architecture (SEDA)

Leonardo Mello Gaona
luizalabs
Published in
3 min readAug 9, 2018

Aqui no Magalu, nossas aplicações enfrentam cargas muito altas de processamento. Por hora, processamos pedidos, consultas de estoque, emitimos notas fiscais e uma infinidade de operações que chegam facilmente na casa dos milhões.

Por isso, construir aplicações com alta performance e escalabilidade está longe de ser um luxo por aqui, é uma necessidade. Recentemente pude participar de um projeto muito bacana e gostaria de compartilhar a experiência com vocês.

O desafio

Atualmente o Magalu possui contratos com diversas transportadoras, além de malha própria para a realização de entregas em todo o território nacional. Ter informações de prazo e preço desatualizadas impacta diretamente nossos clientes, causando uma péssima experiência.

O desafio era automatizar o sincronismo dessas informações diariamente, acabando com o processo manual. Processo aliás, feito por diversos analistas do CD e com incontáveis planilhas de Excel que chegava a levar semanas.

Por conta do volume de operações que essa aplicação teria que aguentar, escalabilidade seria um fator decisivo. E foi por isso que construímos nossa aplicação utilizando arquitetura SEDA.

SEDA?

SEDA é o acrônimo para Staged Event Driven Architecture. Simplificando ao extremo e no meu entendimento, seu princípio é realizar o processamento do todo em pequenos estágios conectados por filas. Exemplos de aplicações atuais que utilizam esse modelo de processamento são o Mule ESB e o Apache Cassandra.

Quando uma requisição chega ao app, ela entra em uma espécie de esteira, onde passa por cada estágio, onde um pool de processadores atua na mensagem e a envia para o próximo estágio, até que todos os estágios sejam percorridos.

E quais os benefícios dessa arquitetura?

  • Desacoplamento total entre os estágios nos permitiria balancear a carga deles de maneira independente: Ou seja, estágios complexos, com um tempo de processamento mais elevado podem receber um número de consumidores maior do que estágios simples.
  • Alta escalabilidade, uma vez que para aumentar o throughput precisamos apenas de mais processos consumindo mensagens das filas ou de mais processadores nos pools.

Módulos da aplicação

A aplicação foi escrita em Go e conta com dois módulos: um scheduler e o worker.

Scheduler

O scheduler apenas executa como uma rotina, recuperando os registros que precisam ser processados e os enfileirando na primeira fila do cluster ActiveMQ. A partir dali, o trabalho é realizado pelos processos do worker.

Worker

Módulo responsável pelo processamento das mensagens. Aqui, de acordo com os pesos configurados, criamos as goroutines que recuperam mensagens das filas do ActiveMQ e também os pools de processadores, que processam essas mensagens e as enviam para a fila seguinte.

Cada fila tem o seu número de assinantes configurado com base em análise das métricas da aplicação

Resultados

O projeto levou pouco mais de 2 semanas para ficar pronto. Até a data de escrita deste artigo, diariamente mantemos atualizadas mais de 306 mil rotas, realizando mais de 4 milhões de requisições em APIs de transportadoras parceiras em um pouco menos de 2 horas.

Os pods worker mal consomem 128mb de memória do cluster
O processo todo roda em pouco menos de 2 horas

Aprendizados da abordagem

Como em todo projeto, sempre tiramos algumas lições:

  • Para não precisarmos gerir a infraestrutura, certificados, SSL etc, optamos por utilizar o serviço do AmazonMQ. Não se preocupar com infra nos deu tempo de sobra para atacar outros pontos da aplicação como mecanismos de re-tentativa, tuning do número de processos, construção de métricas e alarmes etc
  • Ter um broker nesses cenários pode ser perigoso por ser um ponto único de falha. Felizmente, o AmazonMQ oferece configuração de failover, mas a inda assim a sua aplicação precisa saber como se comportar caso o broker principal caia.
  • Geração de métricas é importante em qualquer app, mas em processos assíncronos o peso delas aumenta exponencialmente. A rastreabilidade se torna um fator de suma importância. O que usamos no projeto foi um ID gerado de acordo com algumas propriedades da rota, o que nos permitiu rastrear o registro por toda a trilha de execução.

Espero que vocês tenham gostado, até a próxima!

--

--