Nota
L'accés a aquesta pàgina requereix autorització. Pots provar d'iniciar sessió o canviar de directori.
L'accés a aquesta pàgina requereix autorització. Pots provar de canviar directoris.
SE APLICA A: Todos los niveles de API Management
Cuando varios fragmentos de directiva necesitan acceso a metadatos compartidos, como datos de configuración comunes, use un enfoque de almacenamiento en caché entre solicitudes para optimizar el rendimiento. En lugar de analizar los metadatos repetidamente en cada fragmento, un enfoque de análisis una vez y caché en todas partes mejora considerablemente el rendimiento al tiempo que garantiza la coherencia de los datos. Con este enfoque, los metadatos se analizan una vez en la primera solicitud cuando la caché está vacía y, a continuación, se recuperan de la memoria caché para todas las solicitudes posteriores hasta que expire la memoria caché o cambie la versión de la memoria caché.
Enfoque recomendado
Este enfoque requiere dos fragmentos: uno para almacenar metadatos compartidos y otro para analizar y almacenar en caché los metadatos.
1. Fragmento de metadatos
El fragmento de metadatos actúa como el único origen de la verdad para los metadatos compartidos a los que acceden otros fragmentos de la canalización:
- Almacenamiento JSON centralizado: almacena todos los metadatos como JSON.
- Configuración de caché: incluye la configuración de caché con control de versiones y duración (Período de vida o TTL).
2. Análisis y almacenamiento en caché de fragmentos
El análisis y el almacenamiento en caché del fragmento implementan los comportamientos siguientes:
-
Operación de análisis único: usa
JObject.Parse()para analizar el JSON almacenado en el fragmento de metadatos una vez al principio de cada solicitud de canalización si la memoria caché está vacía. -
Almacenamiento en caché entre solicitudes: almacena y recupera secciones de metadatos analizados como un
JObjectmediante las directivas integradas cache-store-value y cache-lookup-value en varias solicitudes. -
Acceso primero a la caché: las solicitudes posteriores recuperan un objeto analizado
JObjectdirectamente desde la memoria caché, lo que proporciona acceso inmediato a todos los fragmentos sin volver a analizar. - Cache invalidation: la caché se actualiza cuando cambia la versión de metadatos o expira el tiempo de vida de la caché (TTL).
Detalles de la implementación
Para implementar este patrón, inserte ambos fragmentos en una definición de directiva de API o producto al principio de la fase de entrada. El fragmento de metadatos debe insertarse primero, seguido del análisis y el almacenamiento en caché del fragmento. Por ejemplo:
<policies>
<inbound>
<base />
<include-fragment fragment-id="metadata-fragment" />
<include-fragment fragment-id="parse-cache-fragment" />
</inbound>
</policies>
Ejemplo de fragmento de metadatos
El metadata-fragment.xml fragmento almacena metadatos JSON compartidos en una variable de contexto denominada metadata-config:
<!-- Single source of truth for all shared metadata -->
<fragment fragment-id="metadata-fragment">
<set-variable name="metadata-config" value="@{return @"{
'cache-settings': {
'config-version': '1.0',
'ttl-seconds': 3600,
'feature-flags': {
'enable-cross-request-cache': true,
'cache-bypass-header': 'X-Config-Cache-Bypass'
}
},
'logging': {
'level': 'INFO',
'enabled': true
},
'rate-limits': {
'premium': { 'requests-per-minute': 1000 },
'standard': { 'requests-per-minute': 100 },
'basic': { 'requests-per-minute': 20 }
}
}";}" />
</fragment>
Ejemplo de fragmento de análisis y almacenamiento en caché
El parse-cache-fragment.xml fragmento analiza el JSON almacenado en la metadata-config variable de contexto una vez y proporciona acceso al objeto resultante JObject. La metadata-config variable ya debe establecerse mediante metadata-fragment.xml:
<fragment fragment-id="parse-cache-fragment">
<!-- Extract cache settings from metadata-config to determine cache version and TTL -->
<set-variable name="cache-config-temp" value="@{
try {
var configStr = context.Variables.GetValueOrDefault<string>("metadata-config", "{}");
if (string.IsNullOrEmpty(configStr) || configStr == "{}") {
return "{\"version\":\"1.0\",\"enabled\":true,\"ttl\":3600}";
}
var tempConfig = JObject.Parse(configStr);
var cacheSettings = tempConfig["cache-settings"] as JObject;
var result = new JObject();
result["version"] = cacheSettings?["config-version"]?.ToString() ?? "1.0";
result["enabled"] = cacheSettings?["feature-flags"]?["enable-cross-request-cache"]?.Value<bool>() ?? true;
result["ttl"] = cacheSettings?["ttl-seconds"]?.Value<int>() ?? 3600;
return result.ToString(Newtonsoft.Json.Formatting.None);
} catch {
return "{\"version\":\"1.0\",\"enabled\":true,\"ttl\":3600}";
}
}" />
<!-- Parse cache configuration -->
<set-variable name="cache-settings-parsed" value="@{
return JObject.Parse(context.Variables.GetValueOrDefault<string>("cache-config-temp", "{}"));
}" />
<!-- Build cache key with version from cache settings -->
<set-variable name="cache-key" value="@{
var settings = context.Variables.GetValueOrDefault<JObject>("cache-settings-parsed");
var version = settings?["version"]?.ToString() ?? "1.0";
return "metadata-config-parsed-v" + version;
}" />
<!-- Try to get from APIM cache -->
<cache-lookup-value key="@(context.Variables.GetValueOrDefault<string>("cache-key"))" variable-name="cached-config" />
<choose>
<when condition="@(context.Variables.ContainsKey("cached-config"))">
<!-- Cache found - Use cached configuration -->
<set-variable name="config-cache-result" value="@(true)" />
<!-- Restore cached config-parsed -->
<set-variable name="config-parsed" value="@(context.Variables.GetValueOrDefault<JObject>("cached-config"))" />
<!-- Extract sections from cached metadata JObject -->
<set-variable name="config-logging" value="@{
var config = context.Variables.GetValueOrDefault<JObject>("config-parsed");
return config["logging"] as JObject ?? new JObject();
}" />
<set-variable name="config-rate-limits" value="@{
var config = context.Variables.GetValueOrDefault<JObject>("config-parsed");
return config["rate-limits"] as JObject ?? new JObject();
}" />
</when>
<otherwise>
<!-- Cache miss - Parse and store in cache -->
<set-variable name="config-cache-result" value="@(false)" />
<!-- Parse metadata-config JSON -->
<set-variable name="config-parsed" value="@{
var configStr = context.Variables.GetValueOrDefault<string>("metadata-config", "{}");
return JObject.Parse(configStr);
}" />
<!-- Extract commonly used sections for direct access -->
<set-variable name="config-logging" value="@{
var config = context.Variables.GetValueOrDefault<JObject>("config-parsed");
return config["logging"] as JObject ?? new JObject();
}" />
<set-variable name="config-rate-limits" value="@{
var config = context.Variables.GetValueOrDefault<JObject>("config-parsed");
return config["rate-limits"] as JObject ?? new JObject();
}" />
<!-- Store parsed metadata JObject in cache -->
<cache-store-value key="@(context.Variables.GetValueOrDefault<string>("cache-key"))"
value="@(context.Variables.GetValueOrDefault<JObject>("config-parsed"))"
duration="@(context.Variables.GetValueOrDefault<JObject>("cache-settings-parsed")?["ttl"]?.Value<int>() ?? 3600)" />
</otherwise>
</choose>
</fragment>
Uso de metadatos en otros fragmentos
Otros fragmentos ahora pueden acceder directamente a secciones de metadatos analizados. Por ejemplo:
<fragment fragment-id="request-logging-fragment">
<!-- Access logging metadata JObject without reparsing -->
<set-variable name="config-logging" value="@{
return context.Variables.GetValueOrDefault<JObject>("config-logging", new JObject());
}" />
</fragment>
Configuración y invalidación de caché
El parse-cache-fragment.xml fragmento usa la configuración de caché almacenada en el metadata-fragment.xml fragmento para determinar el comportamiento y la invalidación del almacenamiento en caché. Por ejemplo, la configuración se puede cambiar de la siguiente manera:
<!-- Example: Updated cache settings in the metadata fragment -->
'cache-settings': {
'config-version': '1.0.1', <!-- Change version to invalidate cache -->
'ttl-seconds': 7200, <!-- Increase TTL to 2 hours -->
'feature-flags': {
'enable-cross-request-cache': true,
'cache-bypass-header': 'X-Config-Cache-Bypass'
}
}
Funcionamiento de la invalidación de caché: El parse-cache-fragment.xml fragmento construye claves de caché mediante el config-version valor (por ejemplo, metadata-config-v1.0.1). Cuando se cambia la versión a 1.0.2, se crea una nueva clave de caché (metadata-config-v1.0.2). Dado que no existe ningún dato almacenado en caché para la nueva clave, el fragmento analiza json de metadatos nuevos.
Para forzar el refresco de caché: Actualice el fragmento config-version en metadata-fragment.xml. Dado que la configuración de caché se analiza en cada solicitud antes de que se produzca la búsqueda de caché, los cambios en la configuración de la caché surten efecto inmediatamente.
Pruebas y depuración
Seguimiento de resultados de caché
El parse-cache-fragment.xml fragmento establece una config-cache-result variable. Esta variable es útil para el registro y en los encabezados de respuesta para la depuración.
<!-- Add cache status to response headers for debugging -->
<set-header name="X-Config-Cache-Result" exists-action="override">
<value>@(context.Variables.GetValueOrDefault<bool>("config-cache-result", false).ToString())</value>
</set-header>
Omisión de caché
Para deshabilitar el almacenamiento en caché, use el encabezado de omisión de caché:
curl -H "X-Config-Cache-Bypass: true" https://your-gateway.com/api
El parse-cache-fragment.xml fragmento comprueba el encabezado de bypass después de analizar la configuración de caché.
<!-- Check if cache bypass is requested -->
<set-variable name="cache-bypass-requested" value="@{
var settings = context.Variables.GetValueOrDefault<JObject>("cache-settings-parsed");
var bypassHeader = settings?["bypass-header"]?.ToString() ?? "X-Config-Cache-Bypass";
return context.Request.Headers.GetValueOrDefault(bypassHeader, "").ToLower() == "true";
}" />
A continuación, la comprobación de omisión se usa en la lógica de decisión de almacenamiento en caché:
<when condition="@{
var settings = context.Variables.GetValueOrDefault<JObject>("cache-settings-parsed");
var enabled = settings?["enabled"]?.Value<bool>() ?? false;
var bypass = context.Variables.GetValueOrDefault<bool>("cache-bypass-requested", false);
return enabled && !bypass;
}">
<!-- Cross-request caching is enabled and not bypassed -->
</when>
procedimientos recomendados
Control de errores de análisis de JSON con el registro de errores y los valores predeterminados
Implemente el control de errores para las operaciones de análisis de JSON para evitar fallos de fragmentos y proporcionar un comportamiento alternativo. Envuelve JObject.Parse() las operaciones en bloques de try-catch con valores predeterminados significativos.
<set-variable name="config-parsed" value="@{
try {
var configJson = context.Variables.GetValueOrDefault<string>("metadata-config", "{}");
return JObject.Parse(configJson);
} catch (Exception ex) {
// Return default configuration on parse failure
return JObject.Parse(@"{
'logging': { 'level': 'ERROR', 'enabled': false },
'rate-limits': { 'default': { 'requests-per-minute': 10 } }
}");
}
}" />
<!-- Log parse error using trace policy -->
<choose>
<when condition="@(context.Variables.ContainsKey("parse-error"))">
<trace source="config-parse" severity="error">
<message>@("JSON parse failed: " + context.Variables.GetValueOrDefault<string>("parse-error"))</message>
</trace>
</when>
</choose>
Contenido relacionado
- Arquitectura para crear canalizaciones de ejecución avanzadas con fragmentos de directiva : patrones fundamentales para diseñar arquitecturas de fragmentos de directivas modulares y escalables con una separación clara de problemas.
- Administración de variables para fragmentos de directiva : guía completa sobre el control de variables de contexto, los patrones de acceso seguro y la comunicación entre fragmentos.
- Inyección de directivas y coordinación con fragmentos : patrones de inyección de fragmentos y coordinación entre las directivas de producto y API.
- Almacenamiento en caché personalizado en Azure API Management : aprenda a almacenar en caché elementos por clave y a modificar la clave mediante encabezados de solicitud.