Runtime y observabilidad con Aspire

Después de que Lino genera servicios, web apps y recursos de infraestructura, Aspire ayuda a ejecutar todo localmente con visibilidad. La observabilidad no es un lujo: muestra si APIs, bases de datos, cache, mensajería y workers están saludables.

En aplicaciones con eventos, Outbox, workers, Redis, RabbitMQ y múltiples módulos, muchos problemas no aparecen solo en la pantalla. Aparecen en logs, colas, jobs, migrations, parámetros y recursos de runtime. Esta sección muestra cómo mirar la solución como un sistema en ejecución, no solo como archivos generados.

Ejecución con Aspire

El AppHost centraliza la ejecución local de la solución. Inicia servicios, aplicaciones web y dependencias como PostgreSQL, Redis, RabbitMQ y workers.

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

Use el dashboard para revisar logs, variables, endpoints y el estado de los recursos. Si un servicio falla al iniciar, comience por el AppHost y por las dependencias que inyecta.

Aspire hace visible la topología local: APIs, aplicaciones web, bases de datos, cache, broker de mensajes y workers aparecen como recursos relacionados. Esta vista ayuda a encontrar fallos de configuración que quedarían ocultos en una ejecución manual, como una connection string incorrecta, un parámetro ausente, un servicio sin endpoint o una dependencia que aún no se inició.

  • Logs: acompañe errores de inicialización, fallos de autenticación, problemas de migrations y mensajes de workers.
  • Endpoints: confirme puertos, URLs, health checks y enlaces a web apps y APIs.
  • Parámetros: valide secrets y variables propagadas a cada servicio.
  • Dependencias: verifique si Redis, RabbitMQ y la base de datos fueron aprovisionados antes de diagnosticar la aplicación.

Recursos de base de datos

Los servicios generados por Lino normalmente tienen sus propios DbContexts, migrations y connection strings. En sistemas modulares, valide si cada módulo usa la base de datos/schema esperado y si las migrations se aplicaron en el lugar correcto.

  • Confirme connection strings por entorno.
  • Ejecute migrations antes de probar flujos dependientes de un schema nuevo.
  • Monitoree fallos de conexión y tiempo de query.
  • Evite usar una base de datos de producción en ejecución local.

En un servicio simple, la base de datos acompaña al servicio. En un servicio modular, la base de datos pertenece al servicio, pero cada módulo puede tener su propio schema, DbContext, migrations y scripts. Esta separación también debe aparecer en la operación: al aplicar migrations, confirme servicio, módulo, provider y entorno antes de ejecutar.

Los fallos de base de datos suelen aparecer como error de API, pero la causa puede estar en el AppHost, en la connection string, en una migration pendiente, en un schema inexistente o en una credencial local. Por eso, el diagnóstico debe empezar por la cadena completa: parámetro en Aspire, recurso de base de datos activo, migration aplicada, DbContext correcto y endpoint llamando al módulo esperado.

Redis y cache

Redis puede usarse para cache, estado temporal, tokens, rate limiting u otros recursos según los templates habilitados. El cache mejora el rendimiento, pero introduce invalidación y consistencia eventual.

Documente claves, tiempo de expiración y origen de los datos. Nunca almacene secrets sensibles en cache sin entender cifrado, expiración y acceso.

Cuando el proyecto usa cache distribuido, varias instancias pueden compartir valores, lo que es útil para escala horizontal. Cuando trabaja solo con cache local en memoria, cada proceso mantiene su propia copia. Esta diferencia afecta el comportamiento en producción, pruebas de carga e invalidación de datos.

PreguntaPor qué importa
¿Cuál es el origen del dato en cache?Define cómo recalcular el valor cuando expira o se invalida.
¿Qué TTL es aceptable?Determina durante cuánto tiempo el sistema tolera datos potencialmente antiguos.
¿El cache es por tenant, usuario o global?Evita filtraciones de datos entre contextos y claves mal modeladas.

RabbitMQ y mensajería

La mensajería sostiene eventos de integración y comunicación asíncrona. Con Outbox, la aplicación no depende de publicar el mensaje en el mismo instante de la transacción; el worker puede intentarlo de nuevo.

  • Verifique exchanges, colas y bindings generados.
  • Monitoree mensajes detenidos y consumidores inactivos.
  • Diseñe handlers idempotentes.
  • Use logs de correlación para seguir el camino del mensaje.

Los eventos de integración son útiles precisamente porque el productor no necesita esperar a todos los consumidores. Pero eso desplaza parte de la complejidad a la operación: los mensajes pueden retrasarse, los consumidores pueden fallar, los payloads pueden cambiar y los handlers pueden ejecutarse más de una vez. La documentación del flujo debe dejar claro qué evento se publica, quién lo consume y qué estado local se actualiza.

Shadow Entities dependen de esta observabilidad. Si una entidad de tenant o usuario se replica a otros módulos por evento, un fallo en el consumidor puede dejar la copia local desactualizada. El sistema debe permitir diagnosticar el evento, el mensaje, el handler y la actualización realizada en la base de datos del módulo consumidor.

Hangfire Dashboard

Cuando los background jobs están habilitados, el Hangfire Dashboard ayuda a inspeccionar jobs recurrentes, fallos, retries y la ejecución del procesamiento de Outbox.

Proteja el dashboard en entornos compartidos. Expone información operativa relevante y no debe quedar público sin autenticación y autorización.

Use el dashboard como herramienta de diagnóstico, no como sustituto de logs y métricas. Muestra colas, intentos e historial de ejecución, pero la investigación completa todavía necesita correlation id, logs estructurados y contexto de negocio para entender por qué falló un job.

  • Retries: verifique si el fallo es transitorio o si el job seguirá fallando indefinidamente.
  • Jobs recurrentes: confirme intervalo, lote y duración media de ejecución.
  • Outbox: observe mensajes detenidos, reprocesamiento y handlers con excepción.
  • Seguridad: restrinja el acceso, porque payloads y errores pueden revelar datos sensibles.

Workers y procesamiento en segundo plano

Los workers ejecutan tareas que no deben bloquear solicitudes HTTP: envío de mensajes, procesamiento de Outbox, limpieza, sincronización e integraciones externas.

  • Use lotes adecuados al volumen.
  • Defina retries y tratamiento de fallos.
  • Registre errores con contexto suficiente para reprocesar.
  • No esconda fallos permanentes en logs genéricos.

Al agregar un worker, defina también frecuencia, tamaño de lote, comportamiento ante fallos e impacto en el dominio. Un worker que lee 100 registros cada pocos segundos tiene un comportamiento operativo diferente de un job diario; ambos deben observarse y dimensionarse según el volumen real.

No ejecute en background aquello que necesita responder inmediatamente al usuario. Use un worker para tareas posteriores, integraciones, notificaciones, reprocesamiento y mantenimiento. Si el caso de uso depende del resultado para completar la transacción, trátelo como flujo síncrono o modele un estado intermedio visible para el usuario.

Se ha producido un error no controlado. Recargar 🗙