Anmerkung
Der Zugriff auf diese Seite erfordert eine Genehmigung. Du kannst versuchen, dich anzumelden oder die Verzeichnisse zu wechseln.
Der Zugriff auf diese Seite erfordert eine Genehmigung. Du kannst versuchen , die Verzeichnisse zu wechseln.
GILT FÜR: Alle API Management-Ebenen
Wenn mehrere Richtlinienfragmente Zugriff auf freigegebene Metadaten wie allgemeine Konfigurationsdaten benötigen, verwenden Sie einen anforderungsübergreifenden Zwischenspeicherungsansatz, um die Leistung zu optimieren. Anstatt Metadaten wiederholt in jedem Fragment zu analysieren, verbessert ein Ansatz des einmaligen Parsens und überall Cachens die Leistung erheblich, während gleichzeitig die Datenkonsistenz sichergestellt wird. Bei diesem Ansatz werden Metadaten einmal in der ersten Anforderung analysiert , wenn der Cache leer ist, und dann aus dem Cache für alle nachfolgenden Anforderungen abgerufen, bis der Cache abläuft oder die Cacheversion geändert wird.
Empfohlene Vorgehensweise
Dieser Ansatz erfordert zwei Fragmente: eines zum Speichern freigegebener Metadaten und eines anderen zum Analysieren und Zwischenspeichern der Metadaten.
1. Metadatenfragment
Das Metadatenfragment dient als einzige Wahrheitsquelle für freigegebene Metadaten, auf die von anderen Fragmenten in der Pipeline zugegriffen wird:
- Zentralisierter JSON-Speicher: Speichert alle Metadaten als JSON.
- Cacheeinstellungen: Umfasst Cacheeinstellungen mit Versionsverwaltung und Dauer (Zeit für Live oder TTL).
2. Fragment für Analyse und Zwischenspeicherung
Das Analyse- und Zwischenspeicherungsfragment implementiert das folgende Verhalten:
-
Einzelner Analysevorgang: Verwendet
JObject.Parse(), um den im Metadatenfragment gespeicherten JSON-Code einmal am Anfang jeder Pipelineanforderung zu analysieren, wenn der Cache leer ist. -
Anforderungsübergreifendes Zwischenspeichern: Speichert und ruft analysierte Metadatenabschnitte mithilfe
JObjectder integrierten Cachespeicherwert- und Cache-Nachschlagewertrichtlinien für mehrere Anforderungen ab. -
Cache-first-Zugriff: Nachfolgende Anforderungen rufen ein analysiertes
JObjectdirekt aus dem Cache ab, wodurch sofortiger Zugriff auf alle Fragmente ohne erneute Analyse ermöglicht wird. - Cache-Invalidierung: Der Cache wird aktualisiert, wenn sich die Metadatenversion ändert oder die Cachedauer (TTL) abläuft.
Details zur Implementierung
Um dieses Muster zu implementieren, fügen Sie beide Fragmente am Anfang der eingehenden Phase in eine Produkt- oder API-Richtliniendefinition ein. Das Metadatenfragment muss zuerst eingefügt werden, gefolgt von dem Analyse- und Zwischenspeicherungsfragment. Beispiel:
<policies>
<inbound>
<base />
<include-fragment fragment-id="metadata-fragment" />
<include-fragment fragment-id="parse-cache-fragment" />
</inbound>
</policies>
Beispiel für Metadatenfragment
Das metadata-fragment.xml Fragment speichert freigegebene JSON-Metadaten in einer Kontextvariablen mit dem Namen 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>
Beispiel zum Analysieren und Zwischenspeichern von Fragmenten
Das parse-cache-fragment.xml Fragment analysiert den JSON-Code, der in der metadata-config Kontextvariable gespeichert ist, einmal und bietet Zugriff auf die resultierende JObject. Die metadata-config Variable muss bereits festgelegt werden durch 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>
Verwenden von Metadaten in anderen Fragmenten
Andere Fragmente können jetzt direkt auf analysierte Metadatenabschnitte zugreifen. Beispiel:
<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>
Cacheeinstellungen und Ungültigheit
Das parse-cache-fragment.xml Fragment verwendet die im metadata-fragment.xml Fragment gespeicherten Cacheeinstellungen, um das Zwischenspeicherungsverhalten und die Ungültigheit zu bestimmen. Beispielsweise können die Einstellungen wie folgt geändert werden:
<!-- 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'
}
}
Funktionsweise der Cache-Ungültigheit: Das parse-cache-fragment.xml Fragment erstellt Cacheschlüssel mithilfe des config-version Werts (z. B metadata-config-v1.0.1. ). Wenn die Version auf 1.0.2 geändert wird, wird ein neuer Cacheschlüssel erstellt (metadata-config-v1.0.2). Da für den neuen Schlüssel keine zwischengespeicherten Daten vorhanden sind, analysiert das Fragment neue Metadaten-JSON.
Cacheaktualisierung erzwingen: Aktualisieren Sie das config-version im metadata-fragment.xml-Fragment. Da die Cacheeinstellungen für jede Anforderung analysiert werden, bevor die Cachesuche auftritt, werden Änderungen an der Cachekonfiguration sofort wirksam.
Testen und Debuggen
Cacheergebnisnachverfolgung
Das parse-cache-fragment.xml Fragment legt eine config-cache-result Variable fest. Diese Variable ist nützlich für die Protokollierung und in Antwortheadern zum Debuggen:
<!-- 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>
Cache-Umgehung
Verwenden Sie den Cacheumgehungsheader, um die Zwischenspeicherung zu deaktivieren:
curl -H "X-Config-Cache-Bypass: true" https://your-gateway.com/api
Das parse-cache-fragment.xml fragment überprüft den Umgehungsheader nach der Analyse von Cacheeinstellungen.
<!-- 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";
}" />
Die Umgehungsprüfung wird dann in der Entscheidungslogik für die Zwischenspeicherung verwendet:
<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>
Bewährte Methoden
Behandeln von JSON-Analysefehlern mit Fehlerprotokollierung und Standardwerten
Implementieren Sie die Fehlerbehandlung für JSON-Analysevorgänge, um Fragmentfehler zu verhindern und Fallbackverhalten bereitzustellen. Verpacken Sie JObject.Parse()-Operationen in Try-Catch-Blöcke mit aussagekräftigen Standardwerten:
<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>
Verwandte Inhalte
- Architektur für die Erstellung erweiterter Ausführungspipelinen mit Richtlinienfragmenten – Grundlegende Muster für das Entwerfen modularer, skalierbarer Richtlinienfragmentarchitekturen mit klarer Trennung von Bedenken.
- Variable Management für Richtlinienfragmente – Umfassende Anleitungen zur Behandlung von Kontextvariablen, sicheren Zugriffsmustern und Interfragmentkommunikation.
- Richtlinieninjektion und Koordination mit Fragmenten – Fragmentinjektionsmuster und Koordination zwischen Produkt- und API-Richtlinien.
- Benutzerdefiniertes Zwischenspeichern in Azure API Management – Erfahren Sie, wie Sie Elemente nach Schlüssel zwischenspeichern und den Schlüssel mithilfe von Anforderungsheadern ändern.