Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
SI APPLICA A: Tutti i livelli di Gestione API
Quando più frammenti di criteri devono accedere a metadati condivisi, ad esempio i dati di configurazione comuni, usare un approccio di memorizzazione nella cache tra richieste per ottimizzare le prestazioni. Invece di analizzare i metadati ripetutamente in ogni frammento, un approccio parse-once, cache-everywhere migliora notevolmente le prestazioni garantendo al tempo stesso la coerenza dei dati. Con questo approccio, i metadati vengono analizzati una volta nella prima richiesta quando la cache è vuota, quindi recuperata dalla cache per tutte le richieste successive fino alla scadenza della cache o alla modifica della versione della cache.
Approccio consigliato
Questo approccio richiede due frammenti: uno per l'archiviazione di metadati condivisi e un altro per l'analisi e la memorizzazione nella cache dei metadati.
1. Frammento di metadati
Il frammento di metadati funge da singola origine di verità per i metadati condivisi a cui accedono altri frammenti nella pipeline:
- Archiviazione JSON centralizzata: archivia tutti i metadati come JSON.
- Impostazioni cache: Includono le impostazioni della cache con il controllo delle versioni e la durata (Time to Live, o TTL).
2. Analisi e memorizzazione nella cache del frammento
Il frammento di analisi e memorizzazione nella cache implementa i comportamenti seguenti:
-
Singola operazione di analisi: usa
JObject.Parse()per analizzare il codice JSON archiviato nel frammento di metadati una sola volta all'inizio di ogni richiesta della pipeline se la cache è vuota. -
Memorizzazione nella cache tra richieste: archivia e recupera le sezioni dei metadati analizzate come oggetto
JObjectusando i criteri cache-store-value e cache-lookup-value predefiniti tra più richieste. -
Accesso cache-first: Le richieste successive recuperano un elemento analizzato
JObjectdirettamente dalla cache, fornendo un accesso immediato a tutti i segmenti senza ripetere l'analisi. - Invalidazione della cache: la cache si aggiorna quando la versione dei metadati cambia o quando la durata della cache (TTL) scade.
Dettagli sull'implementazione
Per implementare questo modello, inserire entrambi i frammenti in una definizione di criteri di prodotto o API all'inizio della fase in ingresso. Il frammento di metadati deve essere inserito per primo, seguito dall'analisi e dal frammento di memorizzazione nella cache. Per esempio:
<policies>
<inbound>
<base />
<include-fragment fragment-id="metadata-fragment" />
<include-fragment fragment-id="parse-cache-fragment" />
</inbound>
</policies>
Esempio di frammento di metadati
Il metadata-fragment.xml frammento archivia i metadati JSON condivisi in variabili di contesto chiamate 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>
Esempio di analisi e archiviazione nella cache di un frammento
Il parse-cache-fragment.xml frammento analizza il codice JSON archiviato nella variabile di metadata-config contesto una sola volta e fornisce l'accesso all'oggetto risultante JObject. La metadata-config variabile deve essere già impostata da 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 dei metadati in altri frammenti
Altri frammenti possono ora accedere direttamente alle sezioni dei metadati analizzate. Per esempio:
<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>
Impostazioni della cache e invalidazione
Il parse-cache-fragment.xml frammento usa le impostazioni della cache archiviate nel metadata-fragment.xml frammento per determinare il comportamento di memorizzazione nella cache e l'invalidazione. Ad esempio, le impostazioni possono essere modificate nel modo seguente:
<!-- 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'
}
}
Funzionamento dell'invalidazione della cache: Il parse-cache-fragment.xml frammento costruisce le chiavi della cache usando il config-version valore , ad esempio metadata-config-v1.0.1. Quando la versione viene modificata in 1.0.2, viene creata una nuova chiave della cache (metadata-config-v1.0.2). Poiché non esistono dati memorizzati nella cache per la nuova chiave, il frammento analizza i metadati JSON aggiornati.
Per forzare l'aggiornamento della cache: Aggiornare il config-version nel frammento metadata-fragment.xml. Poiché le impostazioni della cache vengono analizzate in ogni richiesta prima che si verifichi la ricerca della cache, le modifiche alla configurazione della cache diventano effettive immediatamente.
Test e debug
Rilevamento dei risultati della cache
Il parse-cache-fragment.xml frammento imposta una config-cache-result variabile. Questa variabile è utile per la registrazione e nelle intestazioni di risposta per il debug:
<!-- 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>
Bypass della cache
Per disabilitare la memorizzazione nella cache, usare l'intestazione di bypass della cache:
curl -H "X-Config-Cache-Bypass: true" https://your-gateway.com/api
Il parse-cache-fragment.xml frammento verifica la presenza dell'intestazione bypass dopo l'analisi delle impostazioni della cache:
<!-- 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";
}" />
Il controllo bypass viene quindi utilizzato nella logica decisionale della cache.
<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>
Procedure consigliate
Gestire gli errori di analisi JSON con la registrazione degli errori e le impostazioni predefinite
Implementare la gestione degli errori per le operazioni di analisi JSON per evitare errori di frammento e fornire il comportamento di fallback. Includere le operazioni JObject.Parse() nei blocchi try-catch con valori di default significativi:
<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>
Contenuti correlati
- Architettura per la creazione di pipeline di esecuzione avanzate con frammenti di criteri : modelli fondamentali per la progettazione di architetture di frammenti di criteri modulari e scalabili con chiara separazione delle problematiche.
- Gestione delle variabili per frammenti di criteri : indicazioni complete sulla gestione delle variabili di contesto, sui modelli di accesso sicuro e sulla comunicazione tra frammenti.
- Inserimento e coordinamento dei criteri con frammenti : modelli di inserimento di frammenti e coordinamento tra i criteri di prodotto e API.
- Memorizzazione nella cache personalizzata in Gestione API di Azure : informazioni su come memorizzare nella cache gli elementi in base alla chiave e modificare la chiave usando le intestazioni della richiesta.