Runtime e observabilidade com Aspire

Depois que o Lino gera serviços, web apps e recursos de infraestrutura, o Aspire ajuda a executar tudo localmente com visibilidade. Observabilidade não é luxo: ela mostra se APIs, bancos, cache, mensageria e workers estão saudáveis.

Em aplicações com eventos, Outbox, workers, Redis, RabbitMQ e múltiplos módulos, muitos problemas não aparecem apenas na tela. Eles aparecem em logs, filas, jobs, migrations, parâmetros e recursos de runtime. Esta seção mostra como olhar para a solução como um sistema em execução, não apenas como arquivos gerados.

Execução com Aspire

O AppHost concentra a execução local da solução. Ele inicia serviços, aplicações web e dependências como PostgreSQL, Redis, RabbitMQ e workers.

dotnet run --project src/Aspire/AppHost/<ProjectName>.AppHost.csproj

Use o dashboard para verificar logs, variáveis, endpoints e estado dos recursos. Se um serviço falhar ao iniciar, comece pelo AppHost e pelas dependências que ele injeta.

O Aspire torna visível a topologia local: APIs, web apps, bancos, cache, broker de mensagens e workers aparecem como recursos relacionados. Essa visão ajuda a encontrar falhas de configuração que ficariam escondidas em uma execução manual, como connection string errada, parâmetro ausente, serviço sem endpoint ou dependência que ainda não subiu.

  • Logs: acompanhe erros de inicialização, falhas de autenticação, problemas de migrations e mensagens de workers.
  • Endpoints: confirme portas, URLs, health checks e links para web apps e APIs.
  • Parâmetros: valide secrets e variáveis propagadas para cada serviço.
  • Dependências: verifique se Redis, RabbitMQ e banco foram provisionados antes de diagnosticar a aplicação.

Recursos de banco de dados

Serviços gerados pelo Lino normalmente têm DbContexts, migrations e connection strings próprias. Em sistemas modulares, valide se cada módulo usa o banco/schema esperado e se migrations foram aplicadas no lugar correto.

  • Confirme connection strings por ambiente.
  • Execute migrations antes de testar fluxos dependentes de schema novo.
  • Monitore falhas de conexão e tempo de query.
  • Evite usar banco de produção em execução local.

Em um serviço simples, o banco acompanha o serviço. Em um serviço modular, o banco pertence ao serviço, mas cada módulo pode ter seu próprio schema, DbContext, migrations e scripts. Essa separação precisa aparecer também na operação: ao aplicar migrations, confirme serviço, módulo, provider e ambiente antes de executar.

Falhas de banco costumam aparecer como erro de API, mas a causa pode estar no AppHost, na connection string, em migration pendente, em schema inexistente ou em credencial local. Por isso, o diagnóstico deve começar pela cadeia completa: parâmetro no Aspire, recurso de banco ativo, migration aplicada, DbContext correto e endpoint chamando o módulo esperado.

Redis e cache

Redis pode ser usado para cache, estado temporário, tokens, rate limiting ou outros recursos dependendo dos templates habilitados. Cache melhora performance, mas introduz invalidação e consistência eventual.

Documente chaves, tempo de expiração e origem dos dados. Nunca armazene segredo sensível em cache sem entender criptografia, expiração e acesso.

Quando o projeto usa cache distribuído, múltiplas instâncias podem compartilhar valores, o que é útil para escala horizontal. Quando trabalha apenas com cache local em memória, cada processo mantém sua própria cópia. Essa diferença afeta comportamento em produção, testes de carga e invalidação de dados.

PerguntaPor que importa
Qual é a origem do dado em cache?Define como recalcular o valor quando expira ou é invalidado.
Qual TTL é aceitável?Determina por quanto tempo o sistema tolera dado potencialmente antigo.
O cache é por tenant, usuário ou global?Evita vazamento de dados entre contextos e chaves mal modeladas.

RabbitMQ e mensageria

Mensageria sustenta eventos de integração e comunicação assíncrona. Com Outbox, a aplicação não depende de publicar a mensagem no mesmo instante da transação; o worker pode tentar novamente.

  • Verifique exchanges, filas e bindings gerados.
  • Monitore mensagens paradas e consumidores inativos.
  • Projete handlers idempotentes.
  • Use logs de correlação para seguir o caminho da mensagem.

Eventos de integração são úteis exatamente porque o produtor não precisa esperar todos os consumidores. Mas isso desloca parte da complexidade para a operação: mensagens podem atrasar, consumidores podem falhar, payloads podem mudar e handlers podem ser executados mais de uma vez. A documentação do fluxo deve deixar claro qual evento é publicado, quem consome e qual estado local é atualizado.

Shadow Entities dependem dessa observabilidade. Se uma entidade de tenant ou usuário é replicada para outros módulos por evento, uma falha no consumidor pode deixar a cópia local desatualizada. O sistema precisa permitir diagnosticar o evento, a mensagem, o handler e a atualização realizada no banco do módulo consumidor.

Hangfire Dashboard

Quando background jobs estão habilitados, o Hangfire Dashboard ajuda a inspecionar jobs recorrentes, falhas, retries e execução de processamento de Outbox.

Proteja o dashboard em ambientes compartilhados. Ele expõe informações operacionais relevantes e não deve ficar público sem autenticação e autorização.

Use o dashboard como ferramenta de diagnóstico, não como substituto de logs e métricas. Ele mostra filas, tentativas e histórico de execução, mas a investigação completa ainda precisa de correlation id, logs estruturados e contexto de negócio para entender por que um job falhou.

  • Retries: verifique se a falha é transitória ou se o job continuará falhando indefinidamente.
  • Jobs recorrentes: confirme intervalo, lote e duração média de execução.
  • Outbox: observe mensagens paradas, reprocessamento e handlers com exceção.
  • Segurança: restrinja acesso, porque payloads e erros podem revelar dados sensíveis.

Workers e processamento em segundo plano

Workers executam tarefas que não devem bloquear requisições HTTP: envio de mensagens, processamento de Outbox, limpeza, sincronização e integrações externas.

  • Use lotes adequados ao volume.
  • Defina retries e tratamento de falhas.
  • Registre erro com contexto suficiente para reprocessar.
  • Não esconda falhas permanentes em logs genéricos.

Ao adicionar worker, defina também frequência, tamanho de lote, comportamento sob falha e impacto no domínio. Um worker que lê 100 registros a cada poucos segundos tem comportamento operacional diferente de um job diário; ambos precisam ser observados e dimensionados conforme volume real.

Não execute em background aquilo que precisa responder imediatamente ao usuário. Use worker para tarefas posteriores, integrações, notificações, reprocessamento e manutenção. Se o caso de uso depende do resultado para completar a transação, trate como fluxo síncrono ou modele um estado intermediário visível para o usuário.

Ocorreu um erro não tratado. Recarregar 🗙