Editar

Compartir a través de


Patrón de aplicaciones web confiables para .NET: Aplicar el patrón

Azure App Service
Azure Front Door
Azure Cache for Redis
.NET

En este artículo se muestra cómo aplicar el patrón Reliable Web App. El patrón Reliable Web App es un conjunto de principios y técnicas de implementación que definen cómo se deben modificar las aplicaciones web (plataforma) al migrar a la nube. Se centra en las actualizaciones mínimas de código que hay que hacer para tener éxito en la nube.

Para facilitar la aplicación de esta guía, hay una implementación de referencia del patrón Reliable Web App que puede implementar.

Diagrama en el que se muestra la arquitectura de la implementación de referencia.Arquitectura de la implementación de referencia. Descargue un archivo de Visio de esta arquitectura.

En las siguientes instrucciones se usa la implementación de referencia como ejemplo. Para aplicar el patrón Reliable Web App, siga estas recomendaciones alineadas con los pilares del marco de trabajo bien diseñado:

Confiabilidad

La confiabilidad garantiza que la aplicación pueda cumplir los compromisos contraídos con los clientes. Para obtener más información, consulte Lista de comprobación de la revisión del diseño para la confiabilidad. El patrón Reliable Web App presenta dos patrones de diseño clave en el nivel de código para mejorar la confiabilidad: el patrón Retry y el patrón Circuit Breaker.

Usar el patrón Retry

El patrón Retry se ocupa de las interrupciones temporales del servicio, denominados fallos transitorios, que suelen resolverse en cuestión de segundos. Estos errores suelen deberse a la limitación del servicio, la distribución dinámica de la carga y los problemas de red en entornos de nube. Implementar el patrón Retry implica reenviar las peticiones erróneas, lo que permite retrasos e intentos configurables antes de conceder el error.

Las aplicaciones que usan el patrón Retry deben integrar los kits de desarrollo de software (SDK) cliente de Azure y los mecanismos de reintento específicos del servicio para mejorar la eficiencia. Las aplicaciones que carezcan de este patrón deberán adoptarlo siguiendo las siguientes directrices.

Pruebe primero los SDK de cliente y servicio de Azure

La mayoría de los servicios de Azure y SDK de cliente incorporan un mecanismo de reintentos. Debe usar el mecanismo de reintentos integrado de los servicios de Azure para acelerar la implementación.

Ejemplo: La implementación de referencia usa el mecanismo de resistencia de conexión en Entity Framework Core para aplicar el patrón Retry a las solicitudes de Azure SQL Database (consulte el siguiente código).

services.AddDbContextPool<ConcertDataContext>(options => options.UseSqlServer(sqlDatabaseConnectionString,
    sqlServerOptionsAction: sqlOptions =>
    {
        sqlOptions.EnableRetryOnFailure(
        maxRetryCount: 5,
        maxRetryDelay: TimeSpan.FromSeconds(3),
        errorNumbersToAdd: null);
    }));

Use la biblioteca Polly cuando la biblioteca cliente no admita reintentos

Es posible que tenga que realizar llamadas a una dependencia que no sea un servicio de Azure o que no admita el patrón de reintentos de forma nativa. En ese caso, debe usar la biblioteca Polly para implementar el patrón de reintentos. Polly es una biblioteca de control de errores transitorios y resistencia de .NET. Con ella, puede usar API fluidas para describir el comportamiento en una ubicación central de la aplicación.

Ejemplo: La implementación de referencia usa Polly para configurar la inserción de dependencias de ASP.NET Core. Polly aplica el patrón de reintentos cada vez que el código construye un objeto que llama al IConcertSearchService objeto. En el marco de Polly, ese comportamiento se conoce como directiva. El código extrae esta directiva en el método GetRetryPolicy y el método GetRetryPolicy aplica el patrón de reintentos cada vez que la aplicación web front-end llama a los servicios de búsqueda de conciertos de API (consulte el siguiente código).

private void AddConcertSearchService(IServiceCollection services)
{
    var baseUri = Configuration["App:RelecloudApi:BaseUri"];
    if (string.IsNullOrWhiteSpace(baseUri))
    {
        services.AddScoped<IConcertSearchService, MockConcertSearchService>();
    }
    else
    {
        services.AddHttpClient<IConcertSearchService, RelecloudApiConcertSearchService>(httpClient =>
        {
            httpClient.BaseAddress = new Uri(baseUri);
            httpClient.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/json");
            httpClient.DefaultRequestHeaders.Add(HeaderNames.UserAgent, "Relecloud.Web");
        })
        .AddPolicyHandler(GetRetryPolicy())
        .AddPolicyHandler(GetCircuitBreakerPolicy());
    }
}

private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
    var delay = Backoff.DecorrelatedJitterBackoffV2(TimeSpan.FromMilliseconds(500), retryCount: 3);
    return HttpPolicyExtensions
      .HandleTransientHttpError()
      .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
      .WaitAndRetryAsync(delay);
}

El controlador de directivas de la RelecloudApiConcertSearchService instancia aplica el patrón de reintentos en todas las solicitudes a la API. Usa la HandleTransientHttpError lógica para detectar solicitudes HTTP que puede reintentar de forma segura y, a continuación, volver a intentar la solicitud en función de la configuración. Incluye cierta aleatoriedad para suavizar las posibles ráfagas en el tráfico a la API si se produce un error.

Uso del patrón Circuit Breaker

El emparejamiento de los patrones Retry y Circuit Breaker expande la capacidad de una aplicación para controlar las interrupciones del servicio que no están relacionadas con errores transitorios. El patrón Circuit Breaker impide que una aplicación intente acceder continuamente a un servicio que no responde. El patrón Circuit Breaker libera la aplicación y evita desperdiciar ciclos de CPU para que la aplicación conserve su integridad de rendimiento para los usuarios finales.

Ejemplo: La implementación de referencia agrega el patrón Circuit Breaker en el GetCircuitBreakerPolicy método (consulte el código siguiente).

private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
{
    return HttpPolicyExtensions
        .HandleTransientHttpError()
        .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
        .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
}

En el código, el controlador de directivas de la instancia RelecloudApiConcertSearchService aplica el patrón Circuit Breaker en todas las solicitudes a la API. Usa la lógica HandleTransientHttpError para detectar solicitudes HTTP que puede reintentar de forma segura, pero limita el número de errores agregados durante un período de tiempo especificado.

Seguridad

La seguridad proporciona garantías contra ataques deliberados y el abuso de datos y sistemas valiosos. Para obtener más información, consulte Lista de comprobación de la revisión del diseño para la seguridad. El patrón Reliable Web App usa identidades administradas para implementar la seguridad centrada en la identidad. Los puntos de conexión privados, el firewall de aplicaciones web y el acceso restringido a la aplicación web proporcionan una entrada segura.

Conceda los privilegios mínimos

Para garantizar la seguridad y la eficiencia, conceda solo a los usuarios (identidades de usuario) y a los servicios de Azure (identidades de carga de trabajo) los permisos que necesitan.

Asigne permisos a las identidades de usuario

Evalúe las necesidades de la aplicación para definir un conjunto de roles que cubran todas las acciones del usuario sin superposición. Asigne cada usuario al rol más adecuado. Asegúrese de que solo tienen acceso a lo necesario para sus tareas.

Asigne permisos a las identidades de carga de trabajo

Conceda solo los permisos críticos para las operaciones, como acciones CRUD en bases de datos o acceso a secretos. Los permisos de identidad de carga de trabajo son persistentes, por lo que no puede proporcionar permisos Just-In-Time o a corto plazo a las identidades de carga de trabajo.

  • Control de acceso basado en rol (RBAC) preferido. Comience siempre con Azure RBAC para asignar permisos. Ofrece un control preciso, lo que garantiza que el acceso sea auditable y granular. Use Azure RBAC para conceder solo los permisos necesarios para que el servicio realice sus funciones deseadas.

  • Complemente con controles de acceso de nivel de servicio de Azure. Si Azure RBAC no cubre un escenario específico, complemente con las directivas de acceso de nivel de servicio de Azure.

Configure la autenticación y la autorización

La autenticación y autorización son aspectos críticos de la seguridad de la aplicación web. La Autenticación es el proceso de verificación de un usuario. La Autorización especifica las acciones que un usuario puede realizar en la aplicación. El objetivo es implementar la autenticación y autorización sin debilitar la posición de seguridad. Para cumplir este objetivo, debe usar las características de la plataforma de aplicaciones de Azure (Azure App Service) y el proveedor de identidades (Microsoft Entra ID).

Configurar autenticación de usuario

Proteja la aplicación web habilitando la autenticación de usuarios a través de las características de la plataforma. App de Azure Service admite la autenticación con proveedores de identidades como Microsoft Entra ID, descargando la carga de trabajo de autenticación desde el código.

Configure la autenticación y autorización del servicio

Configure la autenticación y autorización de servicios para que los servicios de su entorno tengan los permisos para realizar las funciones necesarias. Use Identidades administradas en Microsoft Entra ID para automatizar la creación y administración de identidades de servicio, lo que elimina la administración manual de credenciales. Una identidad administrada permite que la aplicación web acceda de forma segura a los servicios de Azure, como Azure Key Vault y las bases de datos. También facilita las integraciones de canalización de CI/CD para las implementaciones en Azure Service App. Sin embargo, en escenarios como implementaciones híbridas o con sistemas heredados, siga usando las soluciones de autenticación locales para simplificar la migración. Transición a identidades administradas cuando el sistema está listo para un enfoque moderno de administración de identidades. Para más información, consulte Supervisión de identidades administradas.

Uso de DefaultAzureCredential para configurar el código

Use DefaultAzureCredential para proporcionar credenciales para el desarrollo local y las identidades administradas en la nube. DefaultAzureCredential genera un TokenCredential para la adquisición de tokens de OAuth. Controla la mayoría de los escenarios del SDK de Azure y las bibliotecas cliente de Microsoft. Detecta el entorno de la aplicación para usar la identidad correcta y solicita tokens de acceso según sea necesario. DefaultAzureCredential simplifica la autenticación para aplicaciones implementadas en Azure. Para más información, consulte DefaultAzureCredential.

Ejemplo: La implementación de referencia usa la clase DefaultAzureCredential durante el inicio para habilitar el uso de la identidad administrada entre la API web y Key Vault (consulte el código siguiente).

builder.Configuration.AddAzureAppConfiguration(options =>
{
     options
        .Connect(new Uri(builder.Configuration["Api:AppConfig:Uri"]), new DefaultAzureCredential())
        .ConfigureKeyVault(kv =>
        {
            // Some of the values coming from Azure App Configuration are stored Key Vault. Use
            // the managed identity of this host for the authentication.
            kv.SetCredential(new DefaultAzureCredential());
        });
});

Uso de la infraestructura como código para crear identidades administradas

Debe usar plantillas de Bicep para crear y configurar la infraestructura de Azure para admitir identidades administradas. Las identidades administradas no usan secretos ni contraseñas, por lo que no necesita Key Vault ni una estrategia de rotación de secretos para garantizar la integridad. Puede almacenar las cadenas de conexión en el servicio App Configuration.

Ejemplo: La implementación de referencia usa plantillas de Bicep para (1) crear la identidad administrada, (2) asociar la identidad a la aplicación web y (3) conceder permiso a la identidad para acceder a la base de datos SQL. El argumento Authentication de la cadena de conexión siguiente indica a la biblioteca cliente de Microsoft que se conecte con una identidad administrada (consulte el código siguiente).

    Server=tcp:my-sql-server.database.windows.net,1433;Initial Catalog=my-sql-database;Authentication=Active Directory Default

Para obtener más información, consulte Conexión a una base de datos SQL desde .NET App Service.

Uso de un almacén de secretos central para administrar secretos

Al mover la aplicación a la nube, use Azure Key Vault para almacenar de forma segura todos estos secretos. Este repositorio centralizado ofrece almacenamiento seguro, rotación de claves, auditoría de acceso y supervisión para servicios que no admiten identidades administradas. En el caso de las configuraciones de la aplicación, se recomienda Azure App Configuration.

Ejemplo: La implementación de referencia almacena los siguientes secretos en Key Vault: (1) el nombre de usuario y la contraseña de la base de datos PostgreSQL, (2) la contraseña de Redis Cache y (3) el secreto de cliente para Microsoft Entra ID asociado a la implementación de Microsoft Authentication Library (MSAL).

No coloque Key Vault en el flujo de solicitud HTTP

desde Key Vault al inicio de la aplicación en lugar de durante cada solicitud HTTP. Key Vault está diseñado para almacenar y recuperar datos confidenciales de forma segura durante la implementación. El acceso de alta frecuencia dentro de las solicitudes HTTP puede superar las funcionalidades de rendimiento de Key Vault, lo que provoca limitaciones en las solicitudes y errores de código de estado HTTP 429. Para obtener más información, consulte Límites de transacciones de Key Vault.

Use un método para acceder a secretos en Key Vault

Al configurar una aplicación web para acceder a los secretos en Key Vault, tiene dos opciones principales:

  • Configuración de la aplicación de App Service: use una configuración de aplicación en App Service para inyectar el secreto directamente como una variable de entorno.

  • Referencia directa del secreto: haga referencia directamente al secreto dentro del código de la aplicación. Agregue una referencia específica en el archivo de propiedades de la aplicación, como application.properties para aplicaciones Java, para que la aplicación se comunique con Key Vault.

Es importante elegir uno de estos métodos y ceñirse a él para simplificar y evitar complejidades innecesarias.

Preferir métodos de acceso temporales

Use permisos temporales para protegerse de accesos no autorizados e infracciones. Use firmas de acceso compartido (SAS) para el acceso temporal. Use SAS de delegación de usuarios para maximizar la seguridad al conceder acceso temporal. Es la única SAS que usa credenciales de Microsoft Entra y no requiere una clave de cuenta de almacenamiento.

Usar puntos de conexión privados

Use puntos de conexión privados en todos los entornos de producción para todos los servicios de Azure compatibles. Los puntos de conexión privados proporcionan conexiones privadas entre los recursos de una red virtual de Azure y los servicios de Azure. De forma predeterminada, la comunicación a la mayoría de los servicios de Azure cruza la red pública de Internet. Los puntos de conexión privados no requieren ningún cambio de código, configuraciones de aplicaciones ni cadenas de conexión. Para más información, consulte Creación de un punto de conexión privado y Procedimientos recomendados para la seguridad de los puntos de conexión.

Ejemplo: Azure App Configuration, Azure SQL Database, Azure Cache for Redis, Azure Storage, Azure App Service y Key Vault usan un punto de conexión privado.

Uso del firewall de aplicaciones web y restricción del tráfico entrante de Internet

Todo el tráfico entrante de Internet a la aplicación web debe pasar a través de un firewall de aplicaciones web para protegerse contra vulnerabilidades de seguridad web comunes. Obligue a todo el tráfico entrante de Internet a pasar a través del equilibrador de carga público, si tiene uno, y el firewall de aplicaciones web.

Ejemplo: La implementación de referencia fuerza todo el tráfico entrante de Internet a través de Front Door y Azure Web Application Firewall. En producción, conserve el nombre de host HTTP original.

Configurar seguridad de base de datos

El acceso de nivel de administrador a la base de datos concede permisos para realizar operaciones con privilegios. Las operaciones con privilegios incluyen la creación y eliminación de bases de datos, la modificación de esquemas de tabla o el cambio de permisos de usuario. A menudo, los desarrolladores necesitan acceso de nivel de administrador para mantener la base de datos o solucionar problemas.

  • Evite los permisos elevados permanentes. Solo debe conceder a los desarrolladores acceso Just-In-Time para realizar operaciones con privilegios. Con el acceso Just-In-Time, los usuarios reciben permisos temporales para realizar tareas con privilegios

  • No asigne permisos elevados a la aplicación. No debe conceder acceso de nivel de administrador a la identidad de la aplicación. Debe configurar el acceso con privilegios mínimos para la aplicación a la base de datos. Esto limita el radio de explosión de errores y las infracciones de seguridad.

Optimización de costos

La optimización de costos trata de buscar formas de reducir los gastos innecesarios y los gastos generales de gestión. Para obtener más información, consulte Lista de comprobación de la revisión del diseño para la optimización de costes. El patrón Reliable Web App implementa técnicas de redimensionamiento, escalado automático y uso eficiente de recursos para una aplicación web de coste más optimizado.

Dimensión correcta de los recursos para cada entorno

Comprenda los diferentes niveles de rendimiento de los servicios de Azure y use solo la SKU adecuada para las necesidades de cada entorno. Los entornos de producción necesitan SKU que cumplan los acuerdos de nivel de servicio (SLA), las características y la escala necesarias para producción. Los entornos que no son de producción normalmente no necesitan las mismas funcionalidades. Para ahorrar más, considere las Opciones de precios de desarrollo/pruebas de Azure, las Reservas de Azure y los Planes de ahorro de Azure para proceso.

Ejemplo: La implementación de referencia usa parámetros de Bicep para desencadenar configuraciones de implementación de recursos. Uno de estos parámetros indica los niveles de recurso (SKU) que se van a implementar. La aplicación web usa las SKU más eficaces y costosas para los entornos de producción y las SKU más baratas para el entorno de no producción (consulte el código siguiente).

var redisCacheSkuName = isProd ? 'Standard' : 'Basic'
var redisCacheFamilyName = isProd ? 'C' : 'C'
var redisCacheCapacity = isProd ? 1 : 0

Uso de escalabilidad automática

El escalado automático automatiza el escalado horizontal para entornos de producción. Escalabilidad automática basada en métricas de rendimiento. Los desencadenadores de rendimiento de uso de CPU son un buen punto de partida si no entiende los criterios de escalado de la aplicación. Debe configurar y adaptar los desencadenadores de escalado (CPU, RAM, red y disco) para que se correspondan con el comportamiento de la aplicación web. No escale verticalmente para hacer frente a los cambios frecuentes de la demanda. Es menos rentable. Para obtener más información, consulte Escalado en Azure App Service y Escalabilidad automática en Microsoft Azure.

Ejemplo: La implementación de referencia usa la siguiente configuración en la plantilla de Bicep. Crea una regla de escalado automático para Azure App Service. La regla escala hasta 10 instancias y el valor predeterminado es una instancia. Utiliza el uso de la CPU como desencadenador para escalar y reducir horizontalmente. La plataforma de hospedaje de aplicaciones web se escala horizontalmente en un 85 % de uso de CPU y se escala en un 60 %. El valor de escalado horizontal del 85 %, en lugar de un porcentaje más cercano al 100 %, proporciona un búfer para protegerse frente al tráfico de usuario acumulado causado por sesiones permanentes. También protege contra altas ráfagas de tráfico mediante el escalado temprano para evitar el uso máximo de CPU. Estas reglas de escalado automático no son universales (consulte el código siguiente).

resource autoScaleRule 'Microsoft.Insights/autoscalesettings@2022-10-01' = if (autoScaleSettings != null) { 
  name: '${name}-autoscale' 
  location: location 
  tags: tags 
  properties: { 
    targetResourceUri: appServicePlan.id 
    enabled: true 
    profiles: [ 
      { 
        name: 'Auto created scale condition' 
        capacity: { 
          minimum: string(zoneRedundant ? 3 : autoScaleSettings!.minCapacity) 
          maximum: string(autoScaleSettings!.maxCapacity) 
          default: string(zoneRedundant ? 3 : autoScaleSettings!.minCapacity) 
        } 
        rules: [ 
          ... 
        ] 
      } 
    ] 
  } 
}

Usar los recursos de manera eficiente

  • Use servicios compartidos. Centralizar y compartir determinados recursos permite optimizar los costes y reducir los gastos generales de gestión. Coloque recursos de red compartidos en la red virtual del concentrador.

    Ejemplo: La implementación de referencia coloca Azure Firewall, Azure Bastion y Key Vault en la red virtual del centro de conectividad.

  • Elimine los entornos que no utilice. Elimine los entornos que no son de producción después de unas horas o durante los días festivos para optimizar el coste. Puede utilizar la infraestructura como código para eliminar recursos de Azure y entornos completos. Quite la declaración del recurso que desea eliminar de la plantilla de Bicep. Use la operación hipotética para obtener una vista previa de los cambios antes de que surtan efecto. Realice una copia de seguridad de los datos que necesita más adelante. Comprenda las dependencias del recurso que va a eliminar. Si hay dependencias, es posible que también tenga que actualizar o quitar esos recursos. Para obtener más información, consulte Operación hipotética de implementación de Bicep.

  • Coloque la funcionalidad. Cuando haya capacidad de sobra, coloque los recursos y la funcionalidad de la aplicación en un único recurso de Azure. Por ejemplo, varias aplicaciones web pueden usar un único servidor (plan de App Service) o una sola caché puede admitir varios tipos de datos.

    Ejemplo: La implementación de referencia usa una sola instancia de Azure Cache for Redis para la administración de sesiones tanto en aplicaciones web front-end (almacenamiento de tokens de carro como en tokens MSAL) como back-end (que contiene datos de próximos conciertos). Opta por la SKU más pequeña de Redis, que ofrece más capacidad de la necesaria, utilizada eficientemente empleando múltiples tipos de datos para controlar los costos.

Excelencia operativa

La excelencia operativa abarca los procesos de las operaciones que implementan una aplicación y la mantienen en ejecución en producción. Para obtener más información, consulte la Lista de comprobación de revisión de diseño para la excelencia operativa. El patrón Reliable Web App implementa la infraestructura como código para las implementaciones de infraestructura y la supervisión de la observabilidad.

Automatizar la implementación

Use una canalización de CI/CD para implementar cambios desde el control de código fuente a producción. Si usa Azure DevOps, debe usar Azure Pipelines. Si usa GitHub, use acciones de GitHub. Azure admite plantillas ARM (JSON), Bicep y Terraform y dispone de plantillas para cada recurso Azure. Para obtener más información, consulte Plantillas de Bicep, Azure Resource Manager y Terraform e Infraestructura repetible.

Ejemplo: La implementación de referencia usa la CLI de Azure Dev e infraestructura como código (plantillas de Bicep) para crear recursos de Azure, configurar la configuración e implementar los recursos necesarios desde una acción de GitHub.

Configuración de la supervisión

Para supervisar su aplicación web, recopile y analice métricas y registros del código de la aplicación, la infraestructura (tiempo de ejecución) y la plataforma (recursos Azure). Agregue una configuración de diagnóstico para cada recurso de Azure de la arquitectura. Cada servicio Azure tiene un conjunto diferente de registros y métricas que puede capturar. Para más más información, consulte Supervisión de la plataforma y Supervisión de App Service.

Supervisión de as métricas de línea base

Use Azure Application Insights para realizar un seguimiento de las métricas de línea de base, como el rendimiento de las solicitudes, la duración media de las solicitudes, los errores y la supervisión de dependencias. Use AddApplicationInsightsTelemetry desde el paquete Microsoft.ApplicationInsights.AspNetCore de NuGet para habilitar la recopilación de telemetría. Para obtener más información, consulte Habilitación de la telemetría de Application Insights e Inserción de dependencias en .NET.

Ejemplo: Implementación de referencia: La implementación de referencia usa el código siguiente para configurar las métricas de línea base en Application Insights (consulte el código siguiente).

public void ConfigureServices(IServiceCollection services)
{
   ...
   services.AddApplicationInsightsTelemetry(Configuration["App:Api:ApplicationInsights:ConnectionString"]);
   ...
}

Cree telemetría personalizada según sea necesario

Use Application Insights para recopilar telemetría personalizada para comprender mejor a los usuarios de la aplicación web. Cree una instancia de la clase TelemetryClient y utilice los métodos TelemetryClient para crear la métrica correcta. Convierta la consulta en un widget de panel de Azure.

Ejemplo: La implementación de referencia agrega métricas que ayudan al equipo de operaciones a identificar que la aplicación web está completando las transacciones correctamente. Valida que la aplicación web está en línea supervisando si los clientes pueden realizar pedidos, no midiendo el número de solicitudes o el uso de CPU. La implementación de referencia usa TelemetryClient a través de la inserción de dependencias y el método TrackEvent para recopilar telemetría en eventos relacionados con la actividad del carro. La telemetría realiza un seguimiento de los vales que los usuarios agregan, quitan y compran (consulte el código siguiente).

  • AddToCart cuenta cuántas veces los usuarios agregan un vale (ConcertID) al carro.
  • RemoveFromCart registra los vales que los usuarios quitan del carro.
  • CheckoutCart registra un evento cada vez que un usuario compra un vale.

this.telemetryClient.TrackEvent cuenta los vales agregados al carro. Proporciona el nombre del evento (AddToCart) y especifica un diccionario que tiene concertId y count (consulte el código siguiente).

this.telemetryClient.TrackEvent("AddToCart", new Dictionary<string, string> {
    { "ConcertId", concertId.ToString() },
    { "Count", count.ToString() }
});

Para más información, vea:

Recopilar métricas basadas en registros

Realice un seguimiento de las métricas basadas en registros para obtener más visibilidad sobre el estado y las métricas esenciales de la aplicación. Puede usar consultas de Lenguaje de consulta Kusto (KQL) en Application Insights para buscar y organizar los datos. Para más información, consulte Métricas basadas en registros de Azure Application Insights y Métricas basadas en registros y preagregadas en Application Insights.

Habilite los diagnósticos de plataforma

Una configuración de diagnóstico en Azure le permite especificar los registros y las métricas de la plataforma que desea recopilar y dónde almacenarlos. Los registros de plataforma son registros integrados que proporcionan información de diagnóstico y auditoría. Puede habilitar los diagnósticos de plataforma para la mayoría de los servicios de Azure, pero cada servicio define sus propias categorías de registro. Los distintos servicios de Azure tienen categorías de registro para elegir.

  • Habilite los diagnósticos para todos los servicios admitidos. Los servicios de Azure crean registros de plataforma automáticamente, pero el servicio no los almacena automáticamente. Necesita habilitar la configuración de diagnóstico para cada servicio y debe habilitarla para cada servicio de Azure que admita diagnósticos.

  • Envíe diagnósticos al mismo destino que los registros de la aplicación. Al habilitar los diagnósticos, elige los registros que desea recopilar y dónde enviarlos. Debe enviar los registros de la plataforma al mismo destino que los registros de aplicación para poder correlacionar los dos conjuntos de datos.

Eficiencia del rendimiento

La eficiencia del rendimiento es la capacidad que tiene la carga de trabajo para escalar con el fin de satisfacer de manera eficiente las demandas que los usuarios hayan realizado sobre ella. Para obtener más información, consulte la Lista de comprobación de la revisión del diseño para la eficiencia. El patrón Reliable Web App usa el patrón Cache-Aside para minimizar la latencia de los datos altamente solicitados.

Uso del patrón Cache-Aside

El patrón Cache-Aside es una estrategia de almacenamiento en caché que mejora la administración de datos en memoria. El patrón asigna a la aplicación la responsabilidad de gestionar las solicitudes de datos y garantizar la coherencia entre la caché y un almacenamiento persistente, como una base de datos. Cuando la aplicación web recibe una solicitud de datos, primero busca en la caché. Si faltan los datos, los recupera de la base de datos, responde a la solicitud y actualiza la caché en consecuencia. Este planteamiento acorta los tiempos de respuesta y mejora el rendimiento, además de reducir la necesidad de aumentar la escala. También refuerza la disponibilidad del servicio al reducir la carga del almacén de datos primario y minimizar los riesgos de interrupción.

Ejemplo: La implementación de referencia mejora la eficiencia de la aplicación mediante el almacenamiento en caché de datos críticos, como la información de los próximos conciertos cruciales para las ventas de vales. Utiliza la caché de memoria distribuida de ASP.NET Core para el almacenamiento de elementos en memoria. La aplicación usa automáticamente Azure Cache for Redis cuando encuentra una cadena de conexión específica. También admite entornos de desarrollo locales sin Redis para simplificar la configuración y reducir los costos y la complejidad. El método (AddAzureCacheForRedis) configura la aplicación para que use Azure Cache for Redis (consulte el código siguiente).

private void AddAzureCacheForRedis(IServiceCollection services)
{
    if (!string.IsNullOrWhiteSpace(Configuration["App:RedisCache:ConnectionString"]))
    {
        services.AddStackExchangeRedisCache(options =>
        {
            options.Configuration = Configuration["App:RedisCache:ConnectionString"];
        });
    }
    else
    {
        services.AddDistributedMemoryCache();
    }
}

Para obtener más información, consulte Almacenamiento en caché distribuido en ASP.NET Core y Método AddDistributedMemoryCache.

Almacenamiento en caché de datos de alta necesidad

Priorice el almacenamiento en caché de los datos a los que se accede con más frecuencia. Identifique los puntos de datos clave que impulsan la involucración del usuario y el rendimiento del sistema. Implemente estrategias de almacenamiento en caché específicamente para estas áreas para optimizar la eficacia del patrón Cache-Aside, lo que reduce significativamente la latencia y la carga de la base de datos. Use Azure Monitor para realizar un seguimiento de la CPU, la memoria y el almacenamiento de la base de datos. Estas métricas le ayudan a determinar si puede usar una SKU de base de datos más pequeña.

Ejemplo: La implementación de referencia almacena en caché los datos que admiten próximos conciertos. La página Próximos conciertos crea la mayoría de las consultas para SQL Database y genera una salida coherente para cada visita. El patrón Cache-Aside almacena en caché los datos después de la primera solicitud de esta página para reducir la carga en la base de datos. El código siguiente usa el método GetUpcomingConcertsAsync para extraer datos de la caché de Redis desde SQL Database. El método rellena la memoria caché con los conciertos más recientes. El método filtra por tiempo, ordena los datos y devuelve los datos al controlador para mostrar los resultados (consulte el código siguiente).

public async Task<ICollection<Concert>> GetUpcomingConcertsAsync(int count)
{
    IList<Concert>? concerts;
    var concertsJson = await this.cache.GetStringAsync(CacheKeys.UpcomingConcerts);
    if (concertsJson != null)
    {
        // There is cached data. Deserialize the JSON data.
        concerts = JsonSerializer.Deserialize<IList<Concert>>(concertsJson);
    }
    else
    {
        // There's nothing in the cache. Retrieve data from the repository and cache it for one hour.
        concerts = await this.database.Concerts.AsNoTracking()
            .Where(c => c.StartTime > DateTimeOffset.UtcNow && c.IsVisible)
            .OrderBy(c => c.StartTime)
            .Take(count)
            .ToListAsync();
        concertsJson = JsonSerializer.Serialize(concerts);
        var cacheOptions = new DistributedCacheEntryOptions {
            AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
        };
        await this.cache.SetStringAsync(CacheKeys.UpcomingConcerts, concertsJson, cacheOptions);
    }
    return concerts ?? new List<Concert>();
}

Mantener actualizados los datos de la memoria caché

Programe actualizaciones de caché periódicas para sincronizarse con los cambios más recientes en la base de datos. Determine la velocidad de actualización óptima en función de la volatilidad de los datos y las necesidades del usuario. Esta práctica garantiza que la aplicación use el patrón Cache-Aside para proporcionar acceso rápido y información actual.

Ejemplo: La implementación de referencia almacena en caché los datos solo durante una hora. Tiene un proceso para borrar la clave de caché cuando cambian los datos. El método CreateConcertAsync borra la clave de caché (consulte el código siguiente).

public async Task<CreateResult> CreateConcertAsync(Concert newConcert)
{
    database.Add(newConcert);
    await this.database.SaveChangesAsync();
    this.cache.Remove(CacheKeys.UpcomingConcerts);
    return CreateResult.SuccessResult(newConcert.Id);
}

Garantizar coherencia de los datos

Implemente mecanismos para actualizar la memoria caché inmediatamente después de cualquier operación de escritura en la base de datos. Use actualizaciones controladas por eventos o clases de administración de datos dedicadas para garantizar la coherencia de la memoria caché. La sincronización coherente de la memoria caché con modificaciones de la base de datos es fundamental para el patrón Cache-Aside.

Ejemplo: La implementación de referencia usa el método UpdateConcertAsync para mantener los datos en la memoria caché coherentes (consulte el código siguiente).

public async Task<UpdateResult> UpdateConcertAsync(Concert existingConcert), 
{
   database.Update(existingConcert);
   await database.SaveChangesAsync();
   this.cache.Remove(CacheKeys.UpcomingConcerts);
   return UpdateResult.SuccessResult();
}

Probar el rendimiento de la base de datos

El rendimiento de la base de datos puede afectar al rendimiento y la escalabilidad de una aplicación. Es importante probar el rendimiento de la base de datos para asegurarse de que está optimizada. Algunas consideraciones clave son elegir la región de nube adecuada, la agrupación de conexiones, el patrón cache-aside y la optimización de consultas.

  • Pruebe los saltos de red. Mover una aplicación a la nube puede introducir saltos de red adicionales y latencia en la base de datos. Debe probar los saltos adicionales introducidos por el nuevo entorno en la nube.

  • Establezca una línea base de rendimiento. Debe usar métricas de rendimiento locales como línea base inicial para comparar el rendimiento de la aplicación en la nube.

Pasos siguientes

Implemente la implementación de referencia siguiendo las instrucciones del repositorio de GitHub. Utilice los siguientes recursos para obtener más información sobre aplicaciones .NET, aplicaciones web, mejores prácticas en la nube y migración.

Ampliación de las aplicaciones de .NET Framework

La implementación de referencia se implementa en una App Service que ejecuta Windows, pero se puede ejecutar en Linux. La plataforma App Service Windows permite mover aplicaciones web de .NET Framework a Azure sin actualizar a versiones más recientes del marco. Para obtener información sobre los planes de App Service linux o las nuevas características y mejoras de rendimiento agregadas a las versiones más recientes de .NET, consulte las instrucciones siguientes.

Introducción a las aplicaciones web en Azure

Para obtener una introducción práctica a las aplicaciones web de .NET en Azure, consulte esta guía para implementar una aplicación web básica de .NET.

Procedimientos recomendados en la nube

Para obtener instrucciones sobre la adopción y la arquitectura de Azure, consulte:

  • Cloud Adoption Framework. Puede ayudar a su organización a preparar y ejecutar una estrategia para crear soluciones en Azure.
  • Marco de buena arquitectura. Un conjunto de principios rectores que se pueden usar para mejorar la calidad de una carga de trabajo

Para las aplicaciones que requieren un SLO mayor que el patrón Reliable Web App, consulte Cargas de trabajo críticas.

Guía de migración

Las siguientes herramientas y recursos pueden ayudarle a migrar recursos locales a Azure.