E-Docs Next-Gen Architecture (E-Docs NA)
A E-Docs Next-Gen Architecture (E-Docs NA) é o projeto de modernização que reescreve o back-end do E-Docs em uma arquitetura de serviços distribuídos, substituindo de forma gradual o núcleo monolítico original. Este artigo descreve a motivação dessa mudança, os padrões de projeto adotados, a estratégia de migração e os números de operação do sistema.
Este artigo é uma visão conceitual da nova arquitetura. O catálogo completo dos módulos que a compõem (com a responsabilidade de cada serviço e suas dependências) está em Arquitetura de Software. Para um exemplo concreto dos padrões aqui descritos aplicados a um caso de uso real, veja o estudo de caso do fluxo de captura de documentos.
Limitações da arquitetura monolítica
O E-Docs Clássico foi construído como uma aplicação predominantemente monolítica, executada em servidores IIS. Esse modelo atendeu bem por vários anos, mas passou a apresentar limitações à medida que o volume de dados e de acessos crescia:
- Desempenho nas consultas: a abertura de caixas de processos ficava lenta, e processos com milhares de atos chegavam a demorar minutos para carregar ou travavam a tela.
- Escalabilidade rígida: subir um novo servidor para absorver um pico de acesso podia levar horas ou dias. Em cenários de demanda repentina, como processos seletivos, essa demora comprometia o atendimento.
- Alto acoplamento: o código tinha muitas dependências internas. Uma correção em uma consulta compartilhada por várias funcionalidades podia gerar efeitos colaterais em outras partes do sistema.
- Dívida técnica e dificuldade de testes: a estrutura antiga inviabilizava testes automatizados de integração. Cada publicação carregava risco, dependendo quase exclusivamente de testes manuais.
- Complexidade concentrada: por estar tudo em um único bloco, a complexidade real do sistema ficava pouco visível, o que dificultava o planejamento das mudanças.
A partir de 2023, definiu-se o caminho: para sustentar a expansão do E-Docs, incluindo os municípios, era necessário substituir o monolito por uma arquitetura de serviços distribuídos. Um requisito orientou o projeto: a transição deve ocorrer com o sistema em produção, sem interrupção do serviço e sem impacto perceptível para os usuários.
Premissas e princípios de projeto
A E-Docs NA se apoia em Clean Architecture, Clean Code e Vertical Slice. Alguns princípios orientam as decisões de projeto:
- Serviços distribuídos com responsabilidades claras: o back-end é dividido em serviços independentes, cada um com repositório de código próprio e esteira de CI/CD dedicada. Eles se comunicam por APIs REST, o que permite evoluir, publicar e escalar cada serviço sem impactar os demais.
- Comunicação sob medida: a arquitetura se inspira em microsserviços, mas evita a comunicação excessiva entre os serviços. Cada chamada de API busca resolver casos de uso específicos, em vez de fragmentar uma operação em muitas idas e voltas.
- Vertical Slice: em vez de camadas horizontais rígidas, cada funcionalidade é implementada de ponta a ponta, de forma isolada. Assim, o código fica específico para o caso de uso e não carrega dependências desnecessárias.
- Front-end preservado, back-end reescrito: na primeira fase da migração, a interface Web e a API Pública permanecem na aplicação atual (o E-Docs Clássico), enquanto a camada de regra de negócio é reescrita na nova arquitetura. Desse modo, a aplicação original é enxugada e a lógica é movida para serviços menores e interligados.
- Evolução tecnológica independente: com serviços separados, fica mais fácil atualizar versões de runtime, bibliotecas e demais dependências de forma isolada, sem precisar mover o sistema inteiro de uma vez.
Ganhos para o desenvolvimento, a manutenção e a gestão
A combinação de serviços distribuídos com código mais limpo traz ganhos diretos para o trabalho da equipe e para a gestão do sistema, em contraste com os problemas do monolito apontados anteriormente:
- Código mais enxuto e objetivo: cada serviço resolve um conjunto delimitado de casos de uso, sobre uma variação enxuta da Clean Architecture, com menos camadas internas e menos dependências. O resultado é um código mais fácil de ler, entender e alterar.
- Menor curva de aprendizado: como cada serviço é menor e tem responsabilidade clara, um desenvolvedor consegue compreendê-lo e se tornar produtivo sem precisar dominar o sistema inteiro de uma vez.
- Trabalho em paralelo e menos conflitos: com repositórios e esteiras de CI/CD separados, equipes diferentes atuam em serviços diferentes ao mesmo tempo, o que reduz a disputa pelo mesmo código e a quantidade de merges e conflitos.
- Mudanças mais contidas: uma alteração tende a ficar restrita ao serviço onde foi feita, diminuindo o risco de efeitos colaterais em outras partes do sistema, um problema recorrente no monolito.
- Mais espaço para testes automatizados: serviços menores e bem delimitados são mais fáceis de cobrir com testes, algo que a estrutura antiga dificultava.
- Complexidade explícita e gerenciável: no modelo de base única, o sistema aparecia como um único bloco, o que escondia a sua real complexidade, inclusive das camadas gerenciais. Com mais de 20 serviços independentes, cada um com seu próprio deploy, essa complexidade fica visível e mensurável: cada módulo passa a contar de forma individual e a aparecer em relatórios, o que apoia o planejamento e a gestão.
Padrões de projeto
Os padrões a seguir são a base técnica do desempenho e da resiliência da nova arquitetura: o CQRS separa leitura e escrita para aliviar o banco de dados; o Outbox Pattern torna confiável a comunicação assíncrona entre serviços; o Dispatch/Process estrutura a execução das operações mais pesadas; e o Result Pattern trata da estabilidade da aplicação sob carga. Ao final, com base nesses padrões, descrevemos as duas classes de operações assíncronas do sistema.
CQRS (Command Query Responsibility Segregation)
À medida que o uso de um sistema cresce, os servidores de aplicação podem ser escalados com relativa facilidade (mais instâncias, mais hardware). O banco de dados, porém, é um recurso mais difícil de escalar. Em algum momento, o volume combinado de leituras e escritas começa a gerar bloqueios (locks) nas tabelas, lentidão nas consultas e, no limite, timeouts.
O CQRS trata esse problema separando as responsabilidades de escrita (command) e leitura (query) em serviços distintos, cada um podendo ser dimensionado de forma independente. Durante um pico de operações de escrita, por exemplo, o serviço de leitura continua rápido e isolado.
No E-Docs, a separação entre command e query é, antes de tudo, uma separação de serviços: cada lado pode adotar técnicas e bibliotecas específicas para escrita ou para consulta. No nível do banco de dados, ela conta com um recurso já em uso e outro planejado:
- IsolationLevel.Snapshot (em uso): técnica do SQL Server que usa versionamento de linhas como alternativa aos níveis de isolamento tradicionais, reduzindo a ocorrência de locks. O E-Docs já utilizava esse recurso antes da nova arquitetura.
- Réplica somente leitura (planejada): manter, além da base principal (primary), uma réplica sincronizada configurada para acesso somente leitura (intent read-only), com os serviços de escrita usando a primary e os de leitura, a réplica, o que dividiria fisicamente a carga sobre os bancos. A adoção enfrentou dificuldades e ainda não está em produção, permanecendo nos planos futuros.
Outbox Pattern
O Outbox Pattern permite que dois serviços se comuniquem por meio de mensagens gravadas em uma tabela do banco de dados, em vez de depender de soluções de mensageria externas como RabbitMQ ou Kafka. A vantagem é poder contar com a atomicidade das transações de um banco relacional para garantir a consistência da operação: a mensagem só existe se a transação que a originou também foi confirmada.
O funcionamento é o seguinte: na mesma transação em que altera os dados de negócio, o emissor grava um evento, cujos dados ficam em colunas próprias da tabela de eventos (entre elas, uma coluna que registra a sua situação), e enfileira uma execução em segundo plano. Um serviço consumidor lê o evento, executa a tarefa e atualiza a situação ao concluir.
O Outbox garante confiabilidade (nenhum evento se perde) e controle de carga (o processamento ocorre em um ritmo adequado, absorvendo picos de demanda). Por isso, é a base de todas as operações assíncronas da E-Docs NA.
Dispatch/Process
As operações mais importantes e pesadas do sistema, como captura, encaminhamento e atos processuais, são complexas e demoradas. Uma captura, por exemplo, salva dados no banco, carimba cada página do PDF, gera e anexa uma página de metadados, aplica um certificado digital e armazena o arquivo, levando, em média, alguns segundos.
Em um cenário tradicional, a thread do servidor web ficaria ocupada durante todo esse tempo. Sob alto volume (a interface Web do E-Docs processa, em média, milhares de requisições por minuto), as requisições começariam a se enfileirar, o consumo de memória e CPU aumentaria e o tempo médio de resposta cresceria até esbarrar no timeout.
O Dispatch/Process evita isso dividindo a operação em duas fases:
- Dispatch: realiza as validações do caso de uso e prepara os dados necessários. Estando tudo correto, grava o evento (via Outbox) e o enfileira para processamento, devolvendo ao requisitante um token (guid) de evento de processamento.
- Process: um serviço em segundo plano executa de fato a funcionalidade, usando os dados preparados no dispatch, e atualiza a situação do evento ao concluir.
Com isso, a thread do servidor web responde rapidamente (executa apenas o dispatch), e o requisitante (web ou API) usa o token para consultar, por polling, se o evento de processamento já terminou. O trabalho pesado acontece de forma assíncrona e controlada.
Result Pattern
O uso excessivo de exceções (exceptions) tem um custo alto: consome bastante memória e gera stack traces pesados. Em um sistema de alto volume, tratar falhas comuns de regra de negócio como exceções pode levar ao esgotamento de recursos e à queda da aplicação nos momentos de maior carga.
A E-Docs NA adota o Result Pattern: as falhas previsíveis de regra de negócio são retornadas como objetos leves de resultado, em vez de serem lançadas como exceções. As exceções ficam reservadas para erros realmente inesperados, e a aplicação se mantém estável mesmo diante de um grande número de falhas de validação.
As duas classes de operações assíncronas
Com o Outbox como base e o Dispatch/Process disponível para os casos mais pesados, as operações assíncronas da E-Docs NA se organizam em duas classes:
- Classe 1 (operações críticas). As operações pesadas já descritas (captura, encaminhamento, atos processuais). Usam o Dispatch/Process e são acompanhadas pelo requisitante, que consulta o token até a conclusão.
- Classe 2 (operações secundárias). Funções de apoio que usam o Outbox diretamente, sem acompanhamento do requisitante, apenas para que aconteçam de forma confiável e com carga controlada. São exemplos a indexação dos dados no motor de busca, o credenciamento dos agentes para leitura dos documentos que recebem em encaminhamentos e processos e o processamento de áudio e vídeo. Antes, muitas dessas funções rodavam in-process (segurando a operação principal) ou como jobs fire-and-forget (sem garantia de execução); na E-Docs NA, passam pelo Outbox.
Esse encadeamento, em que a conclusão de uma operação dispara as próximas, permite dividir um fluxo complexo em etapas independentes e resilientes, e é ilustrado em detalhe no estudo de caso do fluxo de captura de documentos.
O Dispatch/Process e o Outbox Pattern já eram usados no E-Docs Clássico; a E-Docs NA os mantém e amplia o alcance do Outbox às operações secundárias. O CQRS e o Result Pattern são as principais adições da nova arquitetura.
Ambiente de operação
Todos os módulos da nova arquitetura são construídos na versão mais recente do .NET. O deployment se baseia em containers, orquestrados pelo Red Hat OpenShift sobre Kubernetes, em sistema operacional Linux, por meio de uma esteira de CI/CD mantida pela equipe de Integração. Toda a operação roda on-premises, dentro do datacenter do Governo do Estado, sediado no PRODEST.
Esse ambiente também contribui para a resiliência. As Startup Probes do Kubernetes funcionam, no E-Docs, também como um aquecimento (warm-up) dos recursos: durante a inicialização, o serviço já estabelece e valida as conexões com bancos de dados e outras APIs. Assim, quando o Kubernetes libera o pod para receber requisições, ele já está pronto e "a quente", sem os atrasos de inicialização de conexões que, de outra forma, afetariam as primeiras chamadas logo após um deploy.
A infraestrutura física e a topologia de servidores que sustentam esse ambiente são detalhadas em Arquitetura de Hardware. Os sistemas com os quais o E-Docs se integra estão descritos em Integrações Estruturantes.
Feature flags
Migrar um sistema crítico para uma arquitetura distribuída exige uma estratégia de implantação que reduza riscos e preserve a continuidade do serviço. O principal recurso para conduzir essa migração de forma controlada são as feature flags. Elas permitem que a nova implementação e a anterior coexistam em produção, com a ativação controlada por um mecanismo de permissões. Na prática, isso possibilita:
- Validar em grupos pequenos: a nova versão é liberada primeiro para usuários internos ou grupos restritos, de modo a coletar retorno com baixo risco.
- Avançar de forma gradual: a ativação avança por grupos de órgãos, dos menores aos maiores, até alcançar todo o governo, controlando o impacto no desempenho a cada etapa.
- Reverter de forma imediata: se um problema for detectado em produção, basta desativar a flag para que os usuários retornem à versão estável anterior, sem necessidade de novos deploys.
Observabilidade e telemetria
A nova arquitetura é acompanhada por recursos de observabilidade que permitem entender o comportamento do sistema em produção, tanto para conduzir a migração com segurança quanto para a operação do dia a dia.
Rastreabilidade e telemetria
O Dynatrace é a peça fundamental da observabilidade do E-Docs. Ele provê rastreabilidade ponta a ponta de cada requisição conforme ela percorre os diferentes serviços, avaliação de erros, alertas em tempo real e dados para a análise qualitativa de tempos de resposta e de uso do sistema, entre outros. Com isso, é possível identificar gargalos de desempenho, como uma consulta de banco lenta ou um atraso na resposta entre serviços, muitas vezes antes que o usuário final perceba o problema.
Registro de logs
A forma como a E-Docs NA registra logs foi totalmente aprimorada. Os serviços usam a biblioteca Serilog em conjunto com a interface padrão de log do .NET, o ILogger, e adotam um uso criterioso dos níveis de log:
- Warning para regras de negócio que falham de forma controlada e esperada, como uma validação que impede uma ação.
- Error para falhas inesperadas, que de fato exigem investigação.
Essa distinção tem um duplo benefício. Por um lado, permite tratar os problemas reais assim que acontecem, sem que fiquem escondidos em meio a ruído. Por outro, permite analisar qualitativamente o comportamento do sistema a partir da quantidade de warnings de regra de negócio registrados: um volume incomum desses avisos pode indicar um comportamento equivocado dos usuários ou alguma lógica entre módulos que não está tratando todos os casos de borda (edge cases).
Números de operação
Os números a seguir, referentes ao final de 2025, dão a dimensão da operação que a arquitetura precisa sustentar:
- Mais de 29 milhões de requisições por dia processadas pelos serviços da nova arquitetura.
- Mais de 150 milhões de documentos capturados ao longo da história do sistema.
- 440 milhões de páginas em PDF armazenadas.
- 96 milhões de assinaturas eletrônicas já realizadas.
- Mais de 100 TB de dados sob gestão, incluindo cerca de 56 TB em arquivos e 40 TB em logs de auditoria.
- 184 vCPUs e quase 1 TB de RAM distribuídos entre servidores de aplicação, bancos de dados e clusters de busca.
- 24 municípios capixabas já atendidos, com a meta de alcançar 40.
Uma única requisição para montar uma caixa de encaminhamentos percorre cinco serviços distintos da arquitetura. Com o uso de cache e do Redis, essa montagem leva, em média, cerca de 70 milissegundos.
Os valores acima são um retrato do final de 2025 e crescem continuamente, à medida que mais órgãos e municípios passam a usar o sistema. Servem para dar a ordem de grandeza da operação, não como medição exata e permanente.
Para se aprofundar
- Arquitetura de Software: o catálogo completo dos módulos do E-Docs Clássico e do E-Docs NA, com a responsabilidade e as dependências de cada serviço.
- Estudo de Caso: Fluxo de Captura de Documentos: os padrões deste artigo aplicados, passo a passo, ao caso de uso mais complexo do sistema.
- Arquitetura de Hardware: a infraestrutura física que sustenta a operação.
- E-Docs Chain: a solução que garante autoria e integridade dos documentos capturados.
- Integrações Estruturantes: os sistemas do Estado com os quais o E-Docs se integra.
- O que é o E-Docs?: a visão geral do sistema, sua história e seu contexto institucional.