Degradación graciable
1) La esencia del enfoque
La degradación graciosa es la transición controlada de un sistema a un modo más simple pero útil cuando hay escasez de recursos, fallas en las dependencias o picos de carga. El objetivo es preservar el núcleo de valor para el usuario y la sostenibilidad de la plataforma, sacrificando capacidades y calidad secundarias.
Propiedades clave:- Previsibilidad: escenarios predeterminados y «escaleras» de degradación.
- Limitación del radio de la lesión: aislamiento de fichas y dependencias.
- Observabilidad: métricas, registros y trazados de «qué nivel de degradación está activo y por qué».
- Reversibilidad: rápido retorno a la normalidad.
2) Principios y límites
1. Mantener lo principal: su SLA/SLO principal (por ejemplo, «compra», «inicio de sesión», «búsqueda») es una prioridad por encima de las secundarias (avatares, recomendaciones, animaciones).
2. Fail-open vs fail-closed:- Seguridad, pagos, derechos - fail-cerrado (mejor rechazo que infracción).
- Contenido en caché, pistas, avatares - fail-open con folback.
- 3. Presupuestos temporales: tiempos de espera de arriba hacia abajo (cliente
- 4. Control de costos: la degradación debe reducir el consumo de CPU/IO/red en lugar de simplemente «ocultar» errores.
3) Niveles de degradación
3. 1 Cliente/UX
Skeletons/playsholder y carga «perezosa» de widgets menores.
UI parcial: unidades críticas cargadas, secundarias - ocultadas/simplificadas.
Caché del lado del cliente: last-known-good (LKG) con la etiqueta «los datos podrían haber quedado obsoletos».
Modo offline: cola de comandos con repetición más tarde (¡idempotencia!).
3. 2 puerta de enlace Edge/CDN/WAF/API
stale-while-revalidate: regalamos el caché, actualizamos el fondo.
Rate limiting & load shedding: si se sobrecarga, restablecemos el tráfico de fondo/anónimo.
Geofence/routing ponderado: el tráfico se desvía a la región saludable más cercana.
3. 3 Capa de servicio
Respuesta parcial: devolvemos parte de los datos + 'warnings'.
Modo sólo lectura: prohibición temporal de mutaciones (banderas).
Brownout: desconexión temporal de fich intensivo en recursos (recomendaciones, enriquecimiento).
Concurrencia adaptativa: disminuimos dinámicamente el paralelismo.
3. 4 Datos/streaming
Caché como fuente de verdad con TTL (temporal): «mejor aproximadamente que de ninguna manera».
Precisión reducida de modelos/algoritmos (path rápido vs accurate path).
Defer/queue: transferir tareas pesadas al fondo (outbox/job queue).
Colas prioritarias: eventos críticos - en una clase separada.
4) «Escaleras» de degradación (playbooks)
Ejemplo para la API de búsqueda:- L0 (norma) → L1: ocultar personalización y pancartas → L2: desactivar sinónimos/búsqueda de fazzi → L3: limitar el tamaño de respuesta y el tiempo de espera a 300 ms → L4: dar resultados de kash 5 min → L5: «read-only & cached only» + cola de solicitudes Un nuevo cálculo.
- Desencadenadores: sobrecarga de CPU> 85% p95> destino, errores> umbral, valor de Kafka> umbral, flap dependencias.
- Acciones: activar la marca X, reducir la concurrencia a N, cambiar la fuente Y a caché.
- Criterios de salida: 10 minutos de métricas verdes, stock por recursos.
5) Políticas de toma de decisiones
5. 1 Presupuesto y SLO erróneos
Utilice error-budget burn rate como disparador brownout/mastding.
Política: «si burn-rate> 4 × dentro de 15 min - incluir L2 de degradación».
5. 2 Admission control
Limitamos el RPS entrante en las rutas críticas para garantizar el p99 y evitar el colapso de las colas.
5. 3 Priorización
Clases: interactive> system> background.
Las prioridades del per-tenant (Gold/Silver/Bronze) y la justicia (fair share).
6) Patrones e implementaciones
6. 1 Load shedding (servidor)
Restablezca las solicitudes antes de que ocupen todos los recursos.
Devuelve '429 '/' 503' con 'Retry-After' y una explicación de la política (para clientes).
Envoy (adaptive concurrency + circuit breaking)
yaml typed_extension_protocol_options:
envoy. filters. http. adaptive_concurrency:
"@type": type. googleapis. com/envoy. extensions. filters. http. adaptive_concurrency. v3. AdaptiveConcurrency gradient_controller_config:
sample_aggregate_percentile: 90 circuit_breakers:
thresholds:
- max_requests: 2000 max_pending_requests: 500 max_connections: 1000
6. 2 Brownout (simplificación temporal)
Idea: reducir el «brillo» (costo) de un fich cuando los recursos están fuera.
kotlin class Brownout(val level: Int) { // 0..3 fun recommendationsEnabled() = level < 2 fun imagesQuality() = if (level >= 2) "low" else "high"
fun timeoutMs() = if (level >= 1) 150 else 300
}
6. 3 Respuesta parcial y advertencias
Campo 'warnings '/' degradation' en la respuesta:json
{
"items": [...],
"degradation": {
"level": 2,
"applied": ["cache_only", "no_personalization"],
"expiresAt": "2025-10-31T14:20:00Z"
}
}
6. 4 Stale-while-revalidate en el borde (Nginx)
nginx proxy_cache_valid 200 10m;
proxy_cache_use_stale error timeout http_500 http_502 http_504 updating;
proxy_cache_background_update on;
6. 5 Sólo interruptor Read (Kubernetes + bandera)
yaml apiVersion: v1 kind: ConfigMap data:
MODE: "read_only"
The code should check MODE and block mutations with a friendly message.
6. 6 Kafka: backpressure y clases de cola
Cambie los consumidores heavy a los más pequeños 'max. poll. records ', limitar el batch de producción y.
Divida los eventos «críticos» y «bulk» por topics/cuotas.
6. 7 UI: graceful fallback
Esconde los widgets «pesados», muestra el caché/esqueleto y marca claramente los datos obsoletos.
7) Ejemplos de configuración
7. 1 Istio: outlier + grupos de prioridad
yaml outlierDetection:
consecutive5xx: 5 interval: 10s baseEjectionTime: 30s maxEjectionPercent: 50
7. 2 Nginx: tráfico de fondo debajo del cuchillo primero
nginx map $http_x_priority $bucket { default low; high high; }
limit_req_zone $binary_remote_addr zone=perip:10m rate=20r/s;
limit_req_status 429;
server {
location /api/critical/ { limit_req zone=perip burst=40 nodelay; }
location /api/background/ {
limit_req zone = perip burst = 5 nodelay; # stricter
}
}
7. 3 Feature flags / kill-switches
Almacenar en configuración dinámica (ConfigMap/Consul), actualización sin versión.
Comparta el per-fich y las banderas globales, lógica las activaciones.
8) Observabilidad
8. 1 Métricas
'degradation _ level {service}' es el nivel actual.
'shed _ requests _ total {route, reason}' - cuánto se ha restablecido y por qué.
'stale _ responses _ total' - Cuántos cachés se emiten.
`read_only_mode_seconds_total`.
`brownout_activations_total{feature}`.
Presupuesto erróneo: tasa burn, proporción de violaciones de SLO.
8. 2 Treasing
Atributos de Spans: 'degraded = true', 'level = 2', 'reason = upstream _ timeout'.
Links entre retrayas/consultas hedged para ver la contribución a las colas.
8. 3 Registros/alertas
Eventos de conmutación de niveles de degradación con las causas y el propietario del cambio.
Alertas al nivel de «relleno» (la degradación se mantiene demasiado tiempo).
9) Gestión de riesgos y seguridad
No degrade la autenticación/autorización/integridad de los datos: mejor fallo.
El enmascaramiento PII se guarda en cualquier modo.
Finanzas/pagos: sólo operaciones idempotentes, tiempos de espera estrictos y reveses; cuando hay dudas - read-only/hold.
10) Anti-patrones
Degradación silenciosa sin pista para el usuario y sin telemetría.
Tormentas Retray en lugar de shedding load y shorts.
Los «rubers» globales sin segmentación son un enorme blast radius.
Mezcla prod y rutas «ligeras» en una sola caché/cola.
Degradación eterna: brownout como «nueva normalidad», criterios de salida olvidados.
Stale-write: intentos de escribir basados en datos obsoletos.
11) Lista de verificación de implementación
- Se ha definido un núcleo de valor y scripts de usuario críticos.
- Compiladas escaleras de degradación por servicios/dominios con disparadores y salidas.
- Se han introducido temporizadores/restricciones y shedding de carga server-side.
- Se han configurado los límites de velocidad y las clases de tráfico prioritarias.
- Implementado response partial, read-only, stale-while-revalidate.
- Integrado feature flags/kill-switches con auditoría.
- Métricas/treysing/alertas para niveles de degradación y causas.
- Ejercicios regulares de día de juego con simulación de sobrecarga/interrupción.
- SLO documentado y política de error-budget → degradación.
12) FAQ
P: ¿Cuándo elegir brownout y cuándo elegir shedding?
R: Si el objetivo es reducir el costo de las solicitudes sin fallos - brownout. Si el objetivo es proteger el sistema cuando ni siquiera la simplificación ayuda - shedding de inicio de sesión.
P: ¿Informar al usuario sobre la degradación?
R: Para escenarios críticos - sí (la etiqueta «modo limitado»). La transparencia reduce el apoyo y el descontento.
P: ¿Se puede hacer que la caché sea la fuente de la verdad?
R: Temporalmente - sí, con SLAs explícitos y marcas de obsolescencia. Está prohibido para mutaciones.
P: ¿Cómo no «romper» hacer retraídas?
R: Tiempos cortos, retroceso exponencial con jitter, idempotencia y límite de intentos; retrait sólo operaciones seguras.
13) Resultados
La degradación agraciada es un contrato arquitectónico y un conjunto de modos de funcionamiento gestionados, habilitados mediante señales de métricas y presupuesto erróneo. Escaleras bien diseñadas, rigurosos timeouts y shedding, caché-folbacks y brownout, además de una potente observabilidad - y su plataforma sigue siendo útil y económica incluso en una tormenta.