En este artículo se proporcionan instrucciones para implementar el patrón Reliable Web App. Este patrón describe cómo modificar (plataforma) las aplicaciones web para la migración a la nube. Proporciona instrucciones de configuración, código y arquitectura prescriptivas que se alinean con los principios de Azure Well-Architected Framework.
¿Por qué el patrón Reliable Web App para .NET?
El patrón Reliable Web App es un conjunto de principios y técnicas de implementación que definen cómo debe replatar las aplicaciones web al migrarlas a la nube. Se centra en las actualizaciones mínimas de código que hay que hacer para tener éxito en la nube. En las instrucciones siguientes se usa una implementación de referencia como ejemplo. Las instrucciones siguen el recorrido de expansión de la empresa ficticia Relecloud para proporcionar contexto empresarial para su recorrido. Antes de implementar el patrón Reliable Web App para .NET, Relecloud tenía una aplicación web de vales local monolítica que usaba el marco de ASP.NET.
Sugerencia
Existe una implementación de referencia (ejemplo) del patrón Reliable Web App. Representa el estado final de la implementación de Reliable Web App para una empresa ficticia denominada Relecloud. Se trata de una aplicación web de producción que incluye todas las actualizaciones de código, arquitectura y configuración comentadas en este artículo. Implemente y utilice la implementación de referencia para guiar su implementación del patrón Reliable Web App.
Cómo implementar el patrón Reliable Web App
En este artículo se incluyen instrucciones de arquitectura, código y configuración para implementar el patrón Reliable Web App. Use los vínculos siguientes para ir a las instrucciones específicas que necesita:
- contexto empresarial. Alinear esta guía con su contexto empresarial y aprender a definir objetivos inmediatos y a largo plazo que impulsan decisiones de replatación.
- guía de arquitectura de . Aprenda a seleccionar los servicios en la nube adecuados y diseñar una arquitectura que cumpla sus requisitos empresariales.
- guía de código. Implementar tres patrones de diseño para mejorar la confiabilidad y la eficacia del rendimiento de la aplicación web en la nube: los patrones Retry, Circuit Breaker y Cache-Aside.
- guía de configuración de . Configure la autenticación y autorización, las identidades administradas, los entornos con derechos, la infraestructura como código y la supervisión.
Contexto empresarial
El primer paso para replanificar una aplicación web es definir sus objetivos empresariales. Debe establecer objetivos inmediatos, como objetivos de nivel de servicio (SLO) y objetivos de optimización de costos, así como objetivos futuros para la aplicación web. Estos objetivos influyen en la elección de servicios en la nube y en la arquitectura de la aplicación web en la nube. Defina un objetivo de SLO para su aplicación web, como un tiempo de actividad del 99,9 %. Calcule el SLA compuesto para todos los servicios que afectan a la disponibilidad de su aplicación web.
Por ejemplo, Relecloud tiene una previsión de ventas positiva y prevé un aumento de la demanda en su aplicación web de venta de entradas. Para satisfacer esta demanda, definieron los objetivos de la aplicación web:
- Aplique cambios de código de bajo costo y de alto valor.
- Alcance un SLO de 99,9%.
- Adoptar prácticas de DevOps.
- Cree entornos optimizados para costos.
- Mejorar la confiabilidad y la seguridad.
La infraestructura local de Relecloud no era una solución rentable para alcanzar estos objetivos. Decidieron que migrar su aplicación web a Azure era la manera más rentable de lograr sus objetivos inmediatos y futuros.
Guía de arquitectura
El Reliable Web App fiable tiene algunos elementos arquitectónicos esenciales. Necesita DNS para administrar la resolución de puntos de conexión, un firewall de aplicaciones web para bloquear el tráfico HTTP malintencionado y un equilibrador de carga para enrutar y ayudar a proteger las solicitudes de usuario entrantes. La plataforma de aplicaciones hospeda el código de la aplicación web y realiza llamadas a todos los servicios back-end a través de puntos de conexión privados en una red virtual. Una herramienta de supervisión del rendimiento de la aplicación captura métricas y registros para ayudarle a comprender la aplicación web.
Figura 1. Elementos arquitectónicos esenciales del patrón Reliable Web App.
Diseño de la arquitectura
Diseñe la infraestructura para admitir las métricas de recuperación , como el objetivo de tiempo de recuperación (RTO) y el objetivo de punto de recuperación (RPO). El RTO afecta a la disponibilidad y debe ser compatible con su SLO. Determine un RPO y configure redundancia de datos para satisfacer el RPO.
Elija la fiabilidad de la infraestructura. Determine cuántas zonas de disponibilidad y regiones necesita para cumplir los requisitos de disponibilidad. Añada zonas y regiones de disponibilidad hasta que el SLA compuesto cumpla su SLO. El patrón Reliable Web App admite varias regiones para una configuración activo-activo o activo-pasivo. Por ejemplo, la implementación de referencia utiliza una configuración activa-pasiva para cumplir un SLO del 99,9 %.
En el caso de una aplicación web de varias regiones, configure el equilibrador de carga para enrutar el tráfico a la segunda región para admitir una configuración activa-activa o activa-pasiva, en función de la necesidad empresarial. Las dos regiones requieren los mismos servicios, salvo que una región tiene una red virtual de concentrador que conecta las regiones. Adopte una topología de red radial para centralizar y compartir recursos, como un firewall de red. Si tiene máquinas virtuales, agregue un host bastión a la red virtual del centro para administrarlas con seguridad mejorada. (Véase la figura 2.)
Ilustración 2. El patrón de Reliable Web App con una segunda región y una topología radial.
Elija una topología de red. Elija la topología de red adecuada para los requisitos web y de red. Si tiene previsto usar varias redes virtuales, use una topología de red de concentrador y radio . Proporciona ventajas de costo, administración y seguridad y opciones de conectividad híbrida a redes locales y virtuales.
Elija los servicios Azure adecuados
Al mover una aplicación web a la nube, debe elegir los servicios de Azure que cumplan los requisitos empresariales y alinearse con las características actuales de la aplicación web local. Esta alineación ayuda a minimizar el esfuerzo de replatación. Por ejemplo, utilice servicios que le permitan mantener el mismo motor de base de datos y sean compatibles con el middleware y los marcos existentes. Las siguientes secciones proporcionan orientación para seleccionar los servicios Azure adecuados para su aplicación web.
Por ejemplo, antes de moverse a la nube, la aplicación web de venta de vales de Relecloud era una aplicación monolítica local ASP.NET. Se ejecutó en dos máquinas virtuales y usó una base de datos de SQL Server. La aplicación web sufrió problemas comunes con la escalabilidad y la implementación de características. Este punto de partida, sus objetivos empresariales y el SLO impulsaron su elección de servicios.
Plataforma de aplicaciones: Utilice Azure App Service como plataforma de aplicaciones. Relecloud eligió App Service como plataforma de aplicaciones por los siguientes motivos:
- Acuerdo de Alto Nivel de Servicio (SLA). Tiene un acuerdo de nivel de servicio elevado que cumple el SLO del entorno de producción de 99,9%.
- Sobrecarga de administración reducida. Es una solución totalmente administrada que controla el escalado, las comprobaciones de estado y el equilibrio de carga.
- Compatibilidad con .NET. Admite la versión de .NET en la que se escribe la aplicación.
- Funcionalidad de contenedorización. La aplicación web puede converger en la nube sin incluir contenedores, pero la plataforma de aplicaciones también admite la contenedorización sin cambiar los servicios de Azure.
- Escalado automático. La aplicación web puede escalar y reducir horizontalmente automáticamente en función del tráfico del usuario y las opciones de configuración. La plataforma también admite la ampliación o reducción para adaptarse a diferentes requisitos de hosting.
administración de identidades: Utilice Microsoft Entra ID como solución de administración de identidades y accesos. Relecloud eligió el identificador de Entra de Microsoft por los siguientes motivos:
- Autenticación y autorización. La aplicación debe autenticar y autorizar a los empleados del centro de llamadas.
- Escalable. Microsoft Entra ID se escala para admitir escenarios más grandes.
- Control de identidad de usuario. Los empleados del centro de llamadas pueden usar sus identidades empresariales existentes.
- Compatibilidad con el protocolo de autorización. Microsoft Entra ID admite OAuth 2.0 para identidades administradas.
Base de datos: Utilice un servicio que le permita mantener el mismo motor de base de datos. Use el árbol de decisión del almacén de datos para guiar la selección. La aplicación web de Relecloud utilizaba SQL Server en sus instalaciones. Querían usar el esquema de base de datos, los procedimientos almacenados y las funciones existentes. Hay varios productos SQL disponibles en Azure, pero Relecloud eligió Azure SQL Database por los siguientes motivos:
- Fiabilidad. El nivel de uso general proporciona un acuerdo de nivel de servicio elevado y redundancia de varias regiones. Puede admitir una carga de usuario elevada.
- Sobrecarga de administración reducida. SQL Database proporciona una instancia administrada de SQL Database.
- Compatibilidad con la migración. Admite la migración de bases de datos desde SQL Server local.
- Coherencia con configuraciones locales. Admite los procedimientos almacenados, funciones y vistas existentes.
- Resiliencia. Admite copias de seguridad y restauración a un momento dado.
- Experiencia y reelaboración mínima. SQL Database permite a Relecloud aprovechar los conocimientos existentes y requiere un trabajo mínimo para adoptar.
Supervisión del rendimiento de las aplicaciones: Use Application Insights para analizar la telemetría de la aplicación. Relecloud decidió utilizar Application Insights por las siguientes razones:
- Integración con Azure Monitor. Proporciona la mejor integración con Azure Monitor.
- Detección de anomalías. Detecta automáticamente anomalías de rendimiento.
- Solución de problemas. Le ayuda a diagnosticar problemas en la aplicación en ejecución.
- Monitorización. Recopila información sobre cómo los usuarios usan la aplicación y le permite realizar un seguimiento sencillo de los eventos personalizados.
- Brecha de visibilidad. La solución local no tenía una solución de supervisión del rendimiento de la aplicación. Application Insights proporciona una integración sencilla con la plataforma y el código de la aplicación.
Caché: Elija si desea agregar una caché a la arquitectura de la aplicación web. azure Cache for Redis es la solución principal de azure cache. Se trata de un almacén de datos administrado en memoria basado en software de Redis. La carga de la aplicación web de Relecloud está muy sesgada hacia ver conciertos y detalles de la ubicación. Relecloud agregó Azure Cache for Redis por los siguientes motivos:
- Sobrecarga de administración reducida. Es un servicio totalmente administrado.
- Velocidad y volumen. Tiene un rendimiento de datos alto y lecturas de baja latencia para los datos a los que se accede con frecuencia y cambian lentamente.
- Compatibilidad diversa. Es una ubicación de caché unificada para que se usen todas las instancias de la aplicación web.
- Almacén de datos externos. Los servidores de aplicaciones locales realizaron el almacenamiento en caché local de máquinas virtuales. Esta configuración no ha descargado datos muy frecuentes y no ha podido invalidar los datos.
- Sesiones no sticky. El estado de la sesión de externalización admite sesiones no de lápiz.
equilibrador de carga: aplicaciones web que usan soluciones PaaS deben usar Azure Front Door, Azure Application Gateway o ambos, en función de la arquitectura y los requisitos de la aplicación web. Utilice el árbol de decisión del equilibrador de carga para elegir el equilibrador de carga adecuado. Relecloud necesitaba un equilibrador de carga de capa 7 que pudiera enrutar el tráfico a través de varias regiones. La empresa necesitaba una aplicación web de varias regiones para satisfacer el SLO de 99.9%. Relecloud eligió Azure Front Door por los siguientes motivos:
- Equilibrio de carga global. Es un equilibrador de carga de nivel 7 que puede enrutar el tráfico entre varias regiones.
- Firewall de aplicaciones web. Se integra de forma nativa con Azure Web Application Firewall.
- Flexibilidad de enrutamiento. Permite que el equipo de la aplicación configure las necesidades de entrada para admitir cambios futuros en la aplicación.
- Aceleración del tráfico. Usa anycast para llegar al punto de presencia de Azure más cercano y encontrar la ruta más rápida a la aplicación web.
- Dominios personalizados. Admite nombres de dominio personalizados con validación de dominio flexible.
- Sondeos de estado. La aplicación requiere una supervisión inteligente del sondeo de estado. Azure Front Door usa las respuestas del sondeo para determinar el mejor origen para enrutar las solicitudes de los clientes.
- Compatibilidad con la supervisión. Admite informes integrados con un panel todo en uno tanto para Azure Front Door como para patrones de seguridad. Puede configurar alertas que se integren con Azure Monitor. Azure Front Door permite que la aplicación registre cada solicitud y los sondeos de estado con errores.
- Protección contra DDoS. Tiene protección contra DDoS de capa 3-4 integrada.
- Red de entrega de contenido. Coloca Relecloud para usar una red de entrega de contenido. La red de entrega de contenido proporciona aceleración del sitio.
Firewall de aplicaciones web: Utiliza Azure Web Application Firewall para proporcionar protección centralizada contra exploits y vulnerabilidades web comunes. Relecloud usa Azure Web Application Firewall por los siguientes motivos:
- Protección global. Proporciona una protección mejorada de aplicaciones web globales sin sacrificar el rendimiento.
- Protección de botnet. El equipo puede supervisar y configurar las opciones para abordar los problemas de seguridad relacionados con las redes de bot.
- Paridad con el entorno local. La solución local se estaba ejecutando detrás de un firewall de aplicaciones web administrado por TI.
- Facilidad de uso. Web Application Firewall se integra con Azure Front Door.
Almacenamiento de configuración: Elija si desea añadir almacenamiento de configuración de la aplicación a su aplicación web. Azure App Configuration es un servicio para la administración central de la configuración de la aplicación y las marcas de características. Revise procedimientos recomendados de App Configuration para decidir si este servicio es una buena opción para la aplicación. Relecloud quería sustituir la configuración basada en archivos por un almacén de configuración central que se integre con la plataforma y el código de la aplicación. Agregaron App Configuration a la arquitectura por los siguientes motivos:
- Flexibilidad. Admite marcas de características. Las marcas de características permiten a los usuarios participar y no en las características preliminares anticipadas en un entorno de producción sin necesidad de volver a implementar la aplicación.
- Compatibilidad con la canalización de Git. El origen de verdad de los datos de configuración debe ser un repositorio de Git. Canalización necesaria para actualizar los datos en el almacén de configuración central.
- Compatibilidad con identidades administradas. Admite identidades administradas para simplificar y ayudar a proteger la conexión al almacén de configuración.
Gestor de secretos: Utilice Azure Key Vault si tiene secretos que administrar en Azure. Puede incorporar Key Vault en aplicaciones .NET mediante el objeto ConfigurationBuilder. La aplicación web local de Relecloud almacena secretos en archivos de configuración de código, pero una práctica de seguridad mejor es almacenar secretos en una ubicación que admita controles RBAC y auditoría. Aunque identidades administradas son la solución preferida para conectarse a los recursos de Azure, Relecloud tenía secretos de aplicación que necesitaban para administrar. Relecloud usó Key Vault por los siguientes motivos:
- Encriptación. Admite el cifrado en reposo y en tránsito.
- Compatibilidad con identidades administradas. Los servicios de aplicación pueden usar identidades administradas para acceder al almacén de secretos.
- Supervisión y registro. Key Vault facilita el acceso de auditoría y genera alertas cuando cambian los secretos almacenados.
- Integración. Key Vault proporciona integración nativa con el almacén de configuración de Azure (App Configuration) y la plataforma de hospedaje web (App Service).
Solución de almacenamiento: Consulte opciones de Almacenamiento de Azure para elegir la solución de almacenamiento adecuada en función de sus requisitos. La aplicación web local de Relecloud tenía almacenamiento en disco montado en cada servidor web, pero el equipo quería utilizar una solución de almacenamiento de datos externa. Relecloud eligió Azure Blob Storage por los siguientes motivos:
- Acceso de seguridad mejorada. La aplicación web puede eliminar los puntos de conexión para acceder al almacenamiento expuesto a la red pública de Internet con acceso anónimo.
- Encriptación. Blob Storage cifra los datos en reposo y en tránsito.
- Resiliencia. Blob Storage admite el almacenamiento con redundancia de zona (ZRS). El almacenamiento con redundancia de zona replica los datos de Azure Storage de forma sincrónica en tres zonas de disponibilidad de Azure en la región primaria. Cada zona de disponibilidad es una ubicación física individual con alimentación, refrigeración y redes independientes. Esta configuración debería hacer que las imágenes de emisión de billetes sean resistentes a las pérdidas.
Seguridad de los puntos de conexión: Use Azure Private Link para acceder a soluciones de plataforma como servicio (PaaS) a través de un punto de conexión privado en la red virtual. El tráfico entre la red virtual y el servicio viaja por la red troncal de Microsoft. Relecloud eligió Vínculo Privado por las siguientes razones:
- Comunicación de seguridad mejorada. Private Link permite que la aplicación acceda de forma privada a los servicios en la plataforma Azure y reduce la superficie de red de los almacenes de datos para ayudar a protegerse contra la pérdida de datos.
- Esfuerzo mínimo. Los puntos de conexión privados admiten la plataforma de aplicaciones web y la plataforma de base de datos que usa la aplicación web. Ambas plataformas reflejan las configuraciones locales existentes, por lo que se requiere un cambio mínimo.
Seguridad de red. Use azure Firewall para controlar el tráfico entrante y saliente en el nivel de red. Use azure Bastion para conectarse a máquinas virtuales con seguridad mejorada, sin exponer puertos RDP/SSH. Relecloud adoptó una topología de red en estrella tipo hub-and-spoke y quería poner los servicios de seguridad de red compartidos en el centro. Azure Firewall mejora la seguridad inspeccionando todo el tráfico saliente desde los radios para aumentar la seguridad de red. Relecloud necesitaba Azure Bastion para implementaciones de seguridad mejorada desde un host de salto en la subred de DevOps.
Guía de código
Para mover correctamente una aplicación web a la nube, debe actualizar el código de la aplicación web con el patrón Reintento, el patrón Circuit Breaker y el patrón Cache-Aside.
Figura 3. Roles de los patrones de diseño.
Cada patrón de diseño proporciona ventajas de diseño de carga de trabajo que se alinean con uno o varios pilares de Well-Architected Framework. A continuación, te ofrecemos una visión general de los patrones que deberías implementar:
Patrón de reintento. El patrón Retry controla los errores transitorios mediante las operaciones de reintento que podrían producir un error intermitente. Implemente este patrón en todas las llamadas salientes a otros servicios de Azure.
Patrón circuit Breaker. El patrón Circuit Breaker impide que una aplicación vuelva a intentar las operaciones que no son transitorias. Implemente este patrón en todas las llamadas salientes a otros servicios de Azure.
Cache-Aside patrón. El patrón Cache-Aside carga datos a petición en una memoria caché desde un almacén de datos. Implemente este patrón en las solicitudes a la base de datos.
Modelo de diseño | Fiabilidad (RE) | Seguridad (SE) | Optimización de costes (OC) | Excelencia operativa (OE) | Eficiencia del rendimiento (PE) | Compatibilidad con los principios de WAF |
---|---|---|---|---|---|---|
Retry pattern (Patrón Retry) | ✔ | RE:07 | ||||
patrón Circuit Breaker | ✔ | ✔ |
RE:03 RE:07 PE:07 PE:11 |
|||
de patrón deCache-Aside | ✔ | ✔ |
RE:05 PE:08 PE:12 |
Implementar el patrón Retry
Añada el patrón Reintentar al código de su aplicación para hacer frente a las interrupciones temporales del servicio. Estas interrupciones se denominan fallos transitorios. Los fallos transitorios suelen resolverse en cuestión de segundos. El patrón Retry permite reenviar solicitudes con errores. También le permite configurar el retraso entre reintentos y el número de intentos que se deben realizar antes de conceder un error.
Use mecanismos de reintento integrados. Use el mecanismo de reintento integrado que la mayoría de los servicios de Azure proporcionan para acelerar la implementación. Por ejemplo, la implementación de referencia usa resistencia de conexión en Entity Framework Core para aplicar el patrón Retry en las solicitudes a SQL Database:
services.AddDbContextPool<ConcertDataContext>(options => options.UseSqlServer(sqlDatabaseConnectionString, sqlServerOptionsAction: sqlOptions => { sqlOptions.EnableRetryOnFailure( maxRetryCount: 5, maxRetryDelay: TimeSpan.FromSeconds(3), errorNumbersToAdd: null); }));
Utilice bibliotecas de programación de reintentos. Para las comunicaciones HTTP, integre una biblioteca de resistencia estándar como Polly o
Microsoft.Extensions.Http.Resilience
. Estas bibliotecas proporcionan mecanismos de reintento completos que son fundamentales para administrar las comunicaciones con servicios web externos. Por ejemplo, la implementación de referencia usa Polly para aplicar el patrón Retry cada vez que el código construye un objeto que llama al objetoIConcertSearchService
: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); }
Implementación del patrón de interruptor
Utilice el patrón Circuit Breaker para administrar las interrupciones del servicio que no sean fallos transitorios. El patrón Circuit Breaker impide que una aplicación intente acceder continuamente a un servicio que no responde. Libera la aplicación y ayuda a evitar la pérdida de ciclos de CPU para que la aplicación conserve su integridad de rendimiento para los usuarios finales.
Por ejemplo, la implementación de referencia aplica el patrón Circuit Breaker en todas las solicitudes a la API. Usa la lógica de 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:
private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
.CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
}
Implementación del patrón Cache-Aside
Añada el patrón Cache-Aside a su aplicación web para mejorar la administración de datos en memoria. El patrón asigna a la aplicación la responsabilidad de controlar las solicitudes de datos y garantizar la coherencia entre la caché y el almacenamiento persistente, como una base de datos. Acorta los tiempos de respuesta y mejora el rendimiento, además de reducir la necesidad de aumentar la escala. También reduce la carga en el almacén de datos principal, lo que mejora la confiabilidad y la optimización de costos. Para implementar el patrón Cache-Aside, siga estas recomendaciones:
Configure la aplicación para utilizar una caché. Las aplicaciones de producción deben usar una caché distribuida de Redis. Esta caché mejora el rendimiento al reducir las consultas de base de datos. También habilita sesiones no de lápiz para que el equilibrador de carga pueda distribuir uniformemente el tráfico. La implementación de referencia usa una caché distribuida de Redis. El método
AddAzureCacheForRedis
configura la aplicación para que use Azure Cache for Redis:private void AddAzureCacheForRedis(IServiceCollection services) { if (!string.IsNullOrWhiteSpace(Configuration["App:RedisCache:ConnectionString"])) { services.AddStackExchangeRedisCache(options => { options.Configuration = Configuration["App:RedisCache:ConnectionString"]; }); } else { services.AddDistributedMemoryCache(); } }
Almacenamiento en caché de datos de alta necesidad. Aplique el patrón de Cache-Aside en datos de alta necesidad para mejorar su eficacia. 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 después de aplicar el patrón de Cache-Aside. Por ejemplo, la implementación de referencia almacena en caché datos muy necesarios para la página Próximos conciertos. El método
GetUpcomingConcertsAsync
extrae datos en la caché de Redis de SQL Database y rellena la memoria caché con los datos de concierto más recientes: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>(); }
Mantenga 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. Use la volatilidad de los datos y las necesidades del usuario para determinar la velocidad de actualización óptima. Esta práctica garantiza que la aplicación use el patrón Cache-Aside para proporcionar acceso rápido e información actual. Por ejemplo, la implementación de referencia almacena en caché los datos solo durante una hora y usa el método
CreateConcertAsync
para borrar la clave de caché cuando cambian los datos:public async Task<CreateResult> CreateConcertAsync(Concert newConcert) { database.Add(newConcert); await this.database.SaveChangesAsync(); this.cache.Remove(CacheKeys.UpcomingConcerts); return CreateResult.SuccessResult(newConcert.Id); }
Aseguramiento de la 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. La implementación de referencia usa el método
UpdateConcertAsync
para mantener los datos en la memoria caché coherentes:public async Task<UpdateResult> UpdateConcertAsync(Concert existingConcert), { database.Update(existingConcert); await database.SaveChangesAsync(); this.cache.Remove(CacheKeys.UpcomingConcerts); return UpdateResult.SuccessResult(); }
Guía de configuración
En las secciones siguientes se proporcionan instrucciones sobre la implementación de las actualizaciones de configuración. Cada sección se ajusta a uno o varios pilares del marco de trabajo bien diseñado.
Configuración | Fiabilidad (RE) | Seguridad (SE) | Optimización de costes (OC) | Excelencia operativa (OE) | Eficiencia del rendimiento (PE) | Compatibilidad con los principios de WAF |
---|---|---|---|---|---|---|
Configure la autenticación y la autorización | ✔ | ✔ |
SE:05 OE:10 |
|||
Implementación de identidades administradas | ✔ | ✔ |
SE:05 OE:10 |
|||
Entornos rightsize | ✔ |
CO:05 CO:06 |
||||
Implementación del escalado automático | ✔ | ✔ | ✔ |
RE:06 CO:12 PE:05 |
||
Automatización de la implementación de recursos | ✔ | OE:05 | ||||
Aplicar la supervisión | ✔ | ✔ | ✔ |
OE:07 PE:04 |
Configure la autenticación y la autorización
Cuando migre aplicaciones web a Azure, configure mecanismos de autenticación y autorización de usuarios. Siga estas recomendaciones:
Utilice una plataforma de identidad. Utilice la plataforma Microsoft Identity para configurar la autenticación de aplicaciones web. Esta plataforma admite aplicaciones que usan un único directorio de Microsoft Entra, varios directorios de Microsoft Entra de diferentes organizaciones e identidades de Microsoft o cuentas sociales.
Cree un registro de aplicación. Microsoft Entra ID requiere un registro de aplicación en el inquilino principal. El registro de la aplicación ayuda a garantizar que los usuarios que obtienen acceso a la aplicación web tengan identidades en el inquilino principal.
Utilice las características de la plataforma. Minimice la necesidad de código de autenticación personalizado utilizando las funciones de la plataforma para autenticar a los usuarios y acceder a los datos. Por ejemplo, App Service proporciona compatibilidad con la autenticación integrada, por lo que puede iniciar sesión de usuarios y acceder a los datos al escribir código mínimo o sin código en la aplicación web.
Haga cumplir la autorización en la aplicación. Use RBAC para asignar privilegios mínimos a roles de aplicación. Defina roles específicos para diferentes acciones de usuario para evitar solapamientos y garantizar la claridad. Asigne usuarios a los roles adecuados y asegúrese de que tienen acceso solo a los recursos y acciones necesarios.
Prefiera el acceso temporal al almacenamiento. Use permisos temporales para proteger contra el acceso no autorizado y las infracciones. Por ejemplo, puede usar firmas de acceso compartido (SAS) para limitar el acceso a un período de tiempo. Use saS de delegación de usuarios para maximizar la seguridad al conceder acceso temporal. Es el único SAS que utiliza credenciales de Microsoft Entra ID y no requiere una clave de cuenta de almacenamiento permanente.
Aplique la autorización en Azure. Utilice Azure RBAC para asignar los mínimos privilegios a las identidades de usuario. RBAC de Azure define los recursos de Azure a los que pueden acceder las identidades, lo que pueden hacer con esos recursos y las áreas a las que tienen acceso.
Evite los permisos elevados permanentes. Use Microsoft Entra Privileged Identity Management para conceder acceso Just-In-Time para las operaciones con privilegios. Por ejemplo, los desarrolladores a menudo necesitan acceso de nivel de administrador para crear/eliminar bases de datos, modificar esquemas de tablas y cambiar permisos de usuario. Cuando se usa el acceso Just-In-Time, las identidades de usuario reciben permisos temporales para realizar tareas con privilegios.
Uso de identidades administradas
Use identidades administradas para todos los servicios de Azure que los admitan. Una identidad administrada permite que los recursos de Azure (identidades de carga de trabajo) se autentiquen e interactúen con otros servicios de Azure sin necesidad de administrar las credenciales. Para simplificar la migración, puede seguir usando soluciones de autenticación locales para sistemas híbridos y heredados, pero debe realizar la transición a identidades administradas lo antes posible. Para implantar identidades administradas, siga estas recomendaciones:
Elija el tipo adecuado de identidad administrada. Prefiera las identidades administradas asignadas por usuario cuando tenga dos o más recursos Azure que necesiten el mismo conjunto de permisos. Este enfoque es más eficaz que crear identidades administradas asignadas por el sistema para cada uno de esos recursos y asignar los mismos permisos a todos ellos. De lo contrario, utilice identidades administradas asignadas por el sistema.
Configure los privilegios mínimos. Use azure RBAC para conceder solo 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. Si Azure RBAC no cubre un escenario específico, complemente Azure RBAC con políticas de acceso a nivel de servicio de Azure.
Proporcione seguridad para los secretos restantes. Almacene los secretos restantes en Azure Key Vault. desde Key Vault al inicio de la aplicación en lugar de durante cada solicitud HTTP. El acceso de alta frecuencia dentro de las solicitudes HTTP puede superar los límites de transacción de Key Vault. Almacene las configuraciones de las aplicaciones en Azure App Configuration.
La implementación de referencia usa el argumento Authentication
en la cadena de conexión de base de datos SQL para que App Service pueda conectarse a la base de datos SQL mediante una identidad administrada: Server=tcp:my-sql-server.database.windows.net,1433;Initial Catalog=my-sql-database;Authentication=Active Directory Default
. Usa DefaultAzureCredential
para permitir que la API web se conecte a Key Vault mediante una identidad administrada:
builder.Configuration.AddAzureAppConfiguration(options =>
{
options
.Connect(new Uri(builder.Configuration["Api:AppConfig:Uri"]), new DefaultAzureCredential())
.ConfigureKeyVault(kv =>
{
// Some of the values coming from App Configuration
// are stored in Key Vault. Use the managed identity
// of this host for the authentication.
kv.SetCredential(new DefaultAzureCredential());
});
});
Entornos rightsize
Use los niveles de rendimiento (SKU) de los servicios de Azure que satisfagan las necesidades de cada entorno sin superarlos. Para aplicar derechos a los entornos, siga estas recomendaciones:
Evaluar los costos. Utilice la calculadora de precios de Azure para estimar el coste de cada entorno.
Entornos de producción optimizados para costos. 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. Supervise continuamente el uso de recursos y ajuste las SKU para alinearlas con las necesidades reales de rendimiento.
entornos de preproducción de optimización de costos.entornos de preproducción deben usar recursos de menor costo y aprovechar los descuentos, como precios de desarrollo y pruebas de Azure. En estos entornos, debe deshabilitar los servicios que no son necesarios. Al mismo tiempo, asegúrese de que entornos de preproducción sean lo suficientemente similares a los entornos de producción para evitar la introducción de riesgos. Mantener este equilibrio garantiza que las pruebas permanezcan vigentes sin incurrir en costos innecesarios.
Use la infraestructura como código (IaC) para definir SKU. Implemente IaC para seleccionar y implementar dinámicamente las SKU correctas en función del entorno. Este enfoque mejora la coherencia y simplifica la administración.
Por ejemplo, la implementación de referencia usa parámetros de Bicep para implementar niveles (SKU) más caros en el entorno de producción:
var redisCacheSkuName = isProd ? 'Standard' : 'Basic'
var redisCacheFamilyName = isProd ? 'C' : 'C'
var redisCacheCapacity = isProd ? 1 : 0
Implementación del escalado automático
El escalado automático ayuda a garantizar que una aplicación web siga siendo resistente, con capacidad de respuesta y capaz de controlar las cargas de trabajo dinámicas de forma eficaz. Para implementar el autoescalado, siga estas recomendaciones:
Automatice la escalabilidad horizontal. Utilice Autoescala de Azure para automatizar el escalado horizontal en entornos de producción. Configure reglas de escalado automático para escalar horizontalmente en función de las métricas clave de rendimiento para que la aplicación pueda controlar cargas variables.
Refine los desencadenadores de escalado. Use el uso de cpu como desencadenador de escalado inicial si no está familiarizado con los requisitos de escalado de la aplicación. Refinar los desencadenadores de escalado para incluir otras métricas como RAM, rendimiento de red y E/S de disco. El objetivo es adaptarse al comportamiento de su aplicación web para mejorar el rendimiento.
Proporcione un búfer de escalabilidad horizontal. Establezca los umbrales de escalado para que se desencadenen antes de alcanzar la capacidad máxima. Por ejemplo, configure el escalado para que se produzca al 85 % de utilización de la CPU en lugar de esperar hasta que alcance el 100 %. Este enfoque proactivo ayuda a mantener el rendimiento y evitar posibles cuellos de botella.
Automatización de la implementación de recursos
Utilice la automatización para implementar y actualizar los recursos y el código de Azure en todos los entornos. Siga estas recomendaciones:
Usar la infraestructura como código. Implemente infraestructura como código mediante canalizaciones de integración continua y entrega continua (CI/CD). Azure proporciona plantillas precompiladas Bicep, ARM (JSON) y Terraform para cada recurso de Azure.
Utilice un pipeline de integración continua y entrega continua (CI/CD). Utilice un pipeline CI/CD para implementar código desde el control de origen a los distintos entornos, como pruebas, preparación y producción. Use Azure Pipelines si trabaja con Azure DevOps. Use Acciones de GitHub para proyectos de GitHub.
Integre las pruebas de unidades. Dé prioridad a la ejecución y superación de todas las pruebas unitarias dentro de su pipeline antes de cualquier implementación en App Services. Incorpore herramientas de cobertura y calidad del código como SonarQube para lograr una cobertura de pruebas exhaustiva.
Adoptar marcos ficticios. Para realizar pruebas que impliquen puntos de conexión externos, use marcos ficticios. Estos marcos permiten crear puntos de conexión simulados. Eliminan la necesidad de configurar puntos de conexión externos reales y garantizar condiciones de prueba uniformes en entornos.
Realice exámenes de seguridad. Use pruebas estáticas de seguridad de aplicaciones (SAST) para buscar errores de seguridad y errores de codificación en el código fuente. Además, realice análisis de composición de software (SCA) para examinar bibliotecas y componentes de terceros para detectar riesgos de seguridad. Las herramientas para estos análisis son fáciles de integrar en GitHub y Azure DevOps.
Aplicar la supervisión
Implemente la supervisión de aplicaciones y plataformas para mejorar la excelencia operativa y la eficacia del rendimiento de su aplicación web. Para implantar la supervisión, siga estas recomendaciones:
Recopile telemetría de aplicaciones. Use de instrucciones automáticas en Azure Application Insights para recopilar datos de telemetría de de aplicaciones, como el rendimiento de las solicitudes, la duración media de la solicitud, los errores y la supervisión de dependencias. No es necesario realizar ningún cambio de código para usar esta telemetría.
La implementación de referencia usa
AddApplicationInsightsTelemetry
delMicrosoft.ApplicationInsights.AspNetCore
del paquete NuGet para habilitar la recopilación de telemetría de :public void ConfigureServices(IServiceCollection services) { ... services.AddApplicationInsightsTelemetry(Configuration["App:Api:ApplicationInsights:ConnectionString"]); ... }
Cree métricas de aplicación personalizadas. Utilice la instrumentación basada en código para la telemetría de aplicaciones personalizadas. Añada el SDK de Application Insights a su código y utilice la API de Application Insights.
La implementación de referencia recopila telemetría sobre eventos relacionados con la actividad de los carritos.
this.telemetryClient.TrackEvent
cuenta los vales agregados al carro. Proporciona el nombre de evento (AddToCart
) y especifica un diccionario que tiene elconcertId
ycount
:this.telemetryClient.TrackEvent("AddToCart", new Dictionary<string, string> { { "ConcertId", concertId.ToString() }, { "Count", count.ToString() } });
Supervise la plataforma. Habilite los diagnósticos para todos los servicios admitidos. Envíe diagnósticos al mismo destino que los registros de aplicación para la correlación. Los servicios de Azure crean registros de plataforma automáticamente, pero solo los almacenan cuando se habilitan los diagnósticos. Habilite la configuración de diagnóstico para cada servicio que admita diagnósticos.
Realice la implementación de referencia
La implementación de referencia guía a los desarrolladores a través de una migración simulada desde una aplicación de ASP.NET local a Azure, resaltando los cambios necesarios durante la fase de adopción inicial. Este ejemplo utiliza una aplicación de venta de entradas de conciertos para la empresa ficticia Relecloud, que vende entradas a través de su aplicación web local. Relecloud estableció los siguientes objetivos para su aplicación web:
- Implemente cambios de código de bajo costo y de alto valor.
- Lograr un SLO de 99,9%.
- Adoptar prácticas de DevOps.
- Cree entornos optimizados para costos.
- Mejorar la confiabilidad y la seguridad.
Relecloud determinó que su infraestructura local no era una solución rentable para cumplir estos objetivos. Decidieron que migrar su aplicación web a Azure era la manera más rentable de lograr sus objetivos inmediatos y futuros. La siguiente arquitectura representa el estado final de la implementación del patrón Reliable Web App de Relecloud.
figura 4. Arquitectura de la implementación de referencia. Descargue un archivo de Visio de esta arquitectura.