Chronus 2 — Sistema de integração assíncrona para geração de relatórios
Problema
Solar é um dos maiores e mais utilizados sistemas da Defensoria Pública, ele é responsável (principalmente, mas não somente) por gerenciar todos os atendimentos realizados pela Defensoria do Estado, tanto que já está sendo utilizado em várias outras Defensorias do Brasil.
Até o início de 2015 o Solar enfrentava diversos problema, onde ele simplesmente parava de responder as solicitações e precisava ser reiniciado para voltar a funcionar, isso estava causando muitos problemas no setor.
Solução
Observando o que estava acontecendo eu deduzi que o problema estava sendo no processo de geração de relatórios, que utilizava o Jasper Server como serviço, ele recebia um número muito grande re solicitações de relatórios e alguns, bem grandes, exigiam muito tempo de processamento e assim bloqueavam novas requisições, gerando assim uma fila de bloqueio e derrubando tudo.
Pensei, bora colocar isso tudo em uma fila, pode parecer uma solução até simples, mas a quase 10 anos atrás, pra muita gente não parecia ser, mas como eu já estava estudando isso a um tempo, achei que seria a oportunidade perfeita para aplicar aquilo.
Eu nem era da equipe que cuidava, mas eu estava vendo que aquilo estava gerando tanto problema e eu tinha convicção que poderia resolver aquilo, tinha certeza? Não fazia a mínima ideia, mas eu tinha que tentar. Na verdade eu já tinha tentando jogar a ideia algumas vezes, mas ninguém tinha me dado muita credibilidade hahahha.
Então falei com o diretor de TI: “me dá ai uma semana que eu vou resolver isso ai”, apostei logo alto e botei o meu na reta, ai sim o diretor autorizou e eu comecei o desenvolvimento.
Mão na massa
Stack incial que foi utilizada
- Ruby 2.1
- Rails 4.0
- Sidekiq
- MongoDB
O funcionamento não era complexo, o Chronus recebia a requisição do sistema de origem, validava e processava, enfileirava-a no Sidekiq e respondia para o sistema que o relatório solicitado estava sendo gerado.
Essa resposta era cacheada, para que se o sistema quisesse verificar o status atual do relatório, conseguisse isso da forma mais rápida possível (cerca de 30ms). Enquanto isso, o relatório esta sendo gerado pelo Jasper.
Ao termino do processo, o Sidekiq expira o cache, atualizando o status do relatório e envia uma chamada de callback para o sistema. Permitindo assim duas abordagens:
- O sistema ao enviar a requisição de relatório, fica monitorando status desse, quando detecta que ele foi gerado, informa o usuário na prórima UI. Ideal para relatórios menores, onde o assistido pode esperar o retorno na página de geração.
- Ou, o sistema ao receber o callback, pode então utilizar o sistema de notificação para avisar ao usuário que seu relatório está concluído, utilizado para relatórios que demoram bastante, dando assim libertade ao usuário de poder sair da página e saber que seu relatório foi finalizado de qualquer lugar.
Esse simples sistema permitiu que depois de mais de 9 anos, o Solar nunca mais teve uma queda gerada “”miteriosamente” no processo de geração de relatório, que era causa de 90% desse tipo de problema, dando assim um uptime de cerca de 99.9%.
Podemos ver aqui que pequenas soluções podem trazer grandes benefícios caso seja bem definida para determinada situação.
PLUS:
Atualmente substituímos o MongoDB por PostgreSQL, o Mongo dava sim uma pequena diferença no tempo de resposta, mas aumentava a complexidade do projeto e essa diferença era irrisória, então por um melhor custo benefício, essa troca foi realizada.
Stack Atual:
- Ruby on Rails
- Sidekiq
- PostgreSQL
- Minio.io (AWS S2 compatible)
- Docker
Obrigado por ler, entre em contato em: https://luizcarvalho.com