Umgang mit Konnektivitätsverlusten
Nach Abschluss eines RPC-Aufrufs wird die Verbindung nicht geschlossen. es ist als frei gekennzeichnet. Daher kann der Server ausfallen oder die Netzwerkkonnektivität kann während oder zwischen Anrufen verloren gehen, während sich eine Verbindung im Pool befindet. Aufgrund der Richtlinie versucht die RPC-Laufzeit diese Aufrufe nur dann erneut, wenn die folgenden beiden Bedingungen erfüllt sind:
- Der Server kann den Aufruf möglicherweise nicht ausführen, oder der Aufruf ist idempotent.
- Der Client kann Wiederholungsversuche leistungseffizient implementieren.
Die folgenden Absätze erweitern und verdeutlichen die beiden Bedingungen.
Ein idempotent-Aufruf ist ein Aufruf, der ohne unerwünschte Nebenwirkungen mehr als einmal auf dem Server ausgeführt werden kann. Beispielsweise ist ein RPC-Aufruf, der den Saldo in der Bank für ein bestimmtes Konto abfragt, idempotent. Wenn dieser Aufruf aufgrund eines Konnektivitätsverlustes zweimal ausgeführt wird, wird kein Schaden angerichtet. Ein weiteres Beispiel für einen idempotenten Aufruf ist das Ändern der Adresse eines Kunden in einer Datenbank. Die zweimalige Ausführung ist in Ordnung, da die zweite Ausführung einfach die bereits aktuelle Adresse durch die gleiche Adresse ersetzt. Ein Vorgang wie "subtrahiert fünfzig Dollar vom Konto xyz" ist nicht idempotent. Der Verlust der Netzwerkkonnektivität sollte nicht zu mehreren Ausführungen eines solchen Aufrufs führen.
Um sicher zu sein, behandelt die RPC-Laufzeit alle Aufrufe als nicht idempotent. Das Attribut [idempotent] wird für ncacn_ip_tcp nicht unterstützt und ignoriert. Daher wird die erste Bedingung in der vorherigen Liste auf den Server reduziert, der den Aufruf möglicherweise nicht ausführen kann.
In vielen Fällen kann die RPC-Laufzeit nicht abschließend feststellen, dass der Aufruf nicht bereits auf dem Server ausgeführt wurde. In solchen Fällen versucht der Client nicht erneut, den Aufruf auszuführen.
Die folgenden Beispiele veranschaulichen, wenn die RPC-Laufzeit einen Aufruf wiederholt oder nicht wiederholt:
Ein Server wird neu gestartet.
Ein einfacher RPC-Aufruf ohne Sicherheit wird für eine Schnittstelle ausgeführt, für die nach dem Neustart kein vorheriger Aufruf erfolgt ist. Da für diese Schnittstelle keine Aufrufe getätigt wurden, versucht die RPC-Laufzeit zunächst, die Verwendung der Schnittstelle auszuhandeln. Es sendet ein Paket über eine Verbindung im Pool. Da der Server neu gestartet wurde und die Verbindung nicht mehr gültig ist, wird ein Fehler zurückgegeben. Da die clientseitige RPC-Laufzeit noch nicht mit dem Senden der Daten für den tatsächlichen Aufruf begonnen hat, stellt der Client fest, dass der Server möglicherweise nicht für diese Daten ausgeführt haben konnte. Daher wird die Verbindung geschlossen und nach einer anderen Verbindung im Pool gesucht. Wenn keine Verbindung gefunden werden kann, wird eine neue Verbindung geöffnet und erneut versucht, die Verwendung der Schnittstelle auszuhandeln. Wenn dies erfolgreich ist, wird der Aufruf ausgeführt (d. a. es wird ein Wiederholungsversuch ausgeführt, da der Fehler vor dem Start des Anrufs erkannt wurde).
Ein RPC-Aufruf mit Sicherheit auf Datenschutzebene (Verschlüsselung) erfolgt für eine Verbindung mit einem bereits ausgehandelten Sicherheitskontext.
Um eine effiziente Leistung zu gewährleisten, verschlüsselt die RPC-Laufzeit das gemarselte Paket inline (über die Klartextdaten). Wenn der Versuch, die Daten zu senden, fehlschlägt, kann die RPC-Laufzeit den Aufruf nicht wiederholen, da die Klartextdaten mit den verschlüsselten Daten überschrieben wurden und die Daten nicht mit einem neuen Sicherheitskontext erneut verschlüsselt werden können. Daher wird kein Wiederholungsversuch durchgeführt.
Beim Senden eines nicht ersten Fragments tritt ein Fehler auf.
Es wird kein Wiederholungsversuch durchgeführt, da die RPC-Laufzeit den Inhalt des ersten Fragments möglicherweise verwirft, sobald es abgeschlossen ist, und keine Möglichkeit hat, das senden des ersten Fragments erneut zu versuchen.
Die RPC-Anforderung wird gesendet.
Der Server bricht die Verbindung ab. Es wird kein Wiederholungsversuch versucht, da RPC nicht erkennen kann, ob der Server den Aufruf empfangen hat und mit der Ausführung begonnen hat.
Wenn der Server einen dynamischen Endpunkt verwendet, löst RPC den Endpunkt während Wiederholungsversuchen nicht erneut auf. Dies bedeutet, dass ein Server, wenn er heruntergefahren und wieder hochgefahren wird, sich möglicherweise auf einem anderen Endpunkt befindet, und RPC den Endpunkt nicht transparent erneut auflöst, wenn ein Aufruf wiederholt wird. Um die erneute Auflösung des Endpunkts zu erzwingen, sollte der RPC-Client RpcBindingReset aufrufen, bevor er einen Aufruf wiederholt.
Wenn ein RPC-Client in vielen dieser Fälle feststellen kann, ob ein Aufruf idempotent ist, oder wenn er Daten speichert, die RPC verwirft, kann er sich entscheiden, einen Wiederholungsmechanismus auf RPC basierend auf RPC zu erstellen.
Hinweis
Wenn der Server ein Cluster ist und die verschiedenen Knoten des Clusters unterschiedliche Versionen der Serversoftware ausführen, kann ein RPC-Wiederholungsversuch den Aufruf im Fall eines Failovers auf einem anderen Knoten des Clusters und möglicherweise auf einer anderen Version des Servers landen. Stellen Sie in solchen Bereitstellungsszenarien sicher, dass der Client nicht auf eine bestimmte Version der Serversoftware angewiesen ist, um einen bestimmten Aufruf auszuführen. Wenn dies der Fall ist, sollte der Client einen Mechanismus über RPC erstellen, der solche Bedingungen erkennt und behandelt.