Verhindern clientseitiger Hänger
Es gibt zwei Möglichkeiten, wie Ihr Client hängen kann: Netzwerkkonnektivität kann dazu führen, dass Serveranforderungen verloren gehen oder der Server selbst abstürzt. Bei Standardoptionen wird bei RPC kein Timeout für einen Anruf ausgeführt, und Ihr Clientthread wartet ewig auf eine Antwort.
Es gibt zwei Methoden, um dies zu verhindern: Keep Alives und Timeouts.
TCP Keep Alives
Der Client kann so eingerichtet werden, dass er den Server regelmäßig pingt, um sicherzustellen, dass der Server aktiv ist und ausgeführt wird. Die Pings sind TCP-Keep-Alives für die ncacn_ip_tcp - und ncacn_http Protokollsequenzen und sind daher effizient in Bezug auf CPU-Auslastung und Netzwerkbandbreite. Um keep alives für einen bestimmten Remoteprozeduraufruf zu aktivieren, verwenden Sie die RpcMgmtSetComTimeout-Funktion , bevor der Aufruf initiiert wird. Diese Funktion akzeptiert ein Bindungshandle und ein Timeout als Argumente. Jeder Remoteprozeduraufruf für dieses Bindungshandle nach RpcMgmtSetComTimeout verwendet das angegebene Timeout.
Der Timeout-Parameter für die RpcMgmtSetComTimeout-Funktion gibt an, wie lange die RPC-Laufzeit wartet, bevor keep alives aktiviert wird. Das Timeout ist ein Wert zwischen 0 und 10, wobei 0 das minimale Timeout und 10 ein unendliches Timeout (kein Timeout) ist. Das Timeout selbst ist nicht in Sekunden; die Übersetzung vom Timeoutwert, der für die RpcMgmtSetComTimeout-Funktion bereitgestellt wird, in Sekunden erfolgt durch die RPC-Laufzeit und ist implementierungsspezifisch.
Die folgende Tabelle enthält die Übersetzung in Sekunden für Windows 2000 und Windows XP. In zukünftigen Versionen von Windows kann die Zuordnung zwischen dem Timeoutparameter und dem Timeoutwert in Sekunden geändert werden:
Timeoutparameter | Tatsächliches Timeout in Sekunden |
---|---|
0 (RPC_C_BINDING_MIN_TIMEOUT) | 120 |
1 | 240 |
2 | 360 |
3 | 480 |
4 | 600 |
5 (RPC_C_BINDING_DEFAULT_TIMEOUT) | 720 |
6 | 840 |
7 | 960 |
8 | 1080 |
9 (RPC_C_BINDING_MAX_TIMEOUT) | 1200 |
10 (RPC_C_BINDING_INFINITE_TIMEOUT) | Unendliches Timeout |
Sobald die Keep Alives aktiviert sind, sendet der Client jede Sekunde ein Keep Alive-Paket. Wenn es keine Bestätigung vom Server für drei oder mehr Keep Alives gibt, deklariert der Client die Verbindung für nicht erfolgreich und schlägt den Remoteprozeduraufruf fehl. Wenn der Server innerhalb des angegebenen Timeouts eine Antwort sendet, wird keep alives nicht aktiviert. Wenn der Server antwortet, um weiterhin aktiv zu bleiben, aber nicht auf den Remoteprozeduraufruf reagiert, sendet der Client weiterhin keep alives. Sobald der Server auf den RPC-Aufruf antwortet, werden die Keep Alives deaktiviert. Für Windows 2000 sind keep alives nur für synchrone RPC-Aufrufe aktiviert. Für Windows XP sind keep alives auch für asynchrone RPC-Aufrufe aktiviert.
Es ist verlockend, keep alives auf den niedrigsten Wert festzulegen, um sicherzustellen, dass die Clientanwendung rechtzeitig auf Netzwerkprobleme reagiert. Eine solche Versuchung sollte sorgfältig geprüft werden, und es sollte geprüft werden, ob ein aggressiver Wert gerechtfertigt ist. Ein Server, der vorübergehend die Konnektivität verliert, wird möglicherweise von zahlreichen Clients überflutet, sobald die Konnektivität wiederhergestellt wurde. Darüber hinaus können lange Rechenaufgaben mehr als zwei Minuten in Anspruch nehmen, und der Server verbringt möglicherweise mehr CPU-Zeit mit antworten, um am Leben zu bleiben, als nützliche Arbeit auszuführen. Daher sollte keep alives mit Moderation verwendet werden. Wenn der Client es nicht tolerieren kann, dass sein Thread über einen langen Zeitraum gebunden wird, sollte asynchroner RPC-Vorgang berücksichtigt werden.
Andere Protokollsequenzen können unterschiedliche Mechanismen zum Erkennen nicht reagierender Server implementieren, je nachdem, welcher Transport verwendet wird. Der ncalrpc-Transport verwendet keine keep alives. Da alle Kommunikationen in ncalrpc lokal sind, reagiert der Server während eines Aufrufs nicht mehr, wenn die RPC-Laufzeit auf dem Client sofort fehlschlägt.
Anruftimeouts
TCP keep alives ist in Ordnung, wenn die Netzwerkkonnektivität verloren geht oder der Server abstürzt. Wenn der Server-Deadlock jedoch im Benutzermodus ausgeführt wird, wird tcp keep alives erfolgreich zurückgegeben, aber der Aufruf wird nie zurückgegeben. Um dieses Szenario zu bewältigen, wurde eine neue Laufzeitoption für Windows XP hinzugefügt: RPC_C_OPT_CALL_TIMEOUT. Diese Option weist die RPC-Laufzeit an, bei jedem Senden einer Anforderung an den Server einen Timer einzurichten. Wenn der Timer abläuft, wird der Aufruf automatisch abgebrochen und mit RPC_S_CALL_CANCELLED abgeschlossen. Solange der Server innerhalb des angegebenen Zeitlimits antwortet, wird der Aufruf vom Client nicht abgebrochen. Dies bedeutet, dass ein Multifragmentaufruf mehr als den Timeoutzeitraum in Anspruch nehmen kann, da jede Antwort vom Server innerhalb des Timeoutzeitraums empfangen wird, obwohl der Zeitraum für alle eingehenden Antworten mehr als der Timeoutzeitraum war.
Wenn ein Anruf abgebrochen wird, wird der Server auch nicht über den Abbruch benachrichtigt. Der Server führt den Aufruf daher wahrscheinlich irgendwann aus, und der Client ignoriert einfach die Antwort vom Server.
Der gefährlichste Fall bei Anruftimeouts besteht darin, eine kurze Timeout einzurichten und den Anruf auf demselben Server erneut zu wiederholen. Das folgende Szenario veranschaulicht die Gefahren dieses Ansatzes:
Stellen Sie sich einen Server vor, der nahezu kapazitätsnah arbeitet. Es verfügt über eine Reihe von Clients mit sehr kurzen Timeouts, z. B. fünf Sekunden. Ein vorübergehender Verlust der Netzwerkkonnektivität oder Überlastung bei einem Router führt zu einem Ausfall der Serverantworten für einige Sekunden. In Ethernet-Netzwerken kann diese Situation leicht durch einen Aktivitätsschub für einen Link verursacht werden, den der Server mit einem anderen Computer teilt. Der Server kann nicht alle Antworten vor dem Timeout von fünf Sekunden senden. Die Clients erhalten, dass ihre Anrufe abgebrochen werden, und versuchen Sie es sofort erneut. Der Server weiß nicht, dass die Aufrufe Wiederholungen sind, und führt sie auch aus. Anstatt die normale Workload der Aufrufe auszuführen, werden also 30 bis 50 % mehr Aufrufe ausgeführt, je nachdem, wie viele Clients das Timeout haben. Wenn dies die Kapazität überschreitet und der Server nicht innerhalb von fünf Sekunden auf alle Clients reagieren kann, wird eine weitere Runde von Anrufen an den Server gesendet. Die Clients führen dieselben Aufrufe immer wieder aus, und da der Server bei der Verarbeitung vorheriger Aufrufe überlastet ist, kann er innerhalb des Timeouts nicht reagieren. Nach der Antwort haben die Clients das Timeout erreicht, einen neuen Anruf ausgegeben und die Antwort verworfen. Im schlimmsten Fall wird der Server erst nach dem Neustart wiederhergestellt, und je nach Clientzugriffsmuster kann die Wiederherstellung erst dann erfolgen, wenn eine ausreichende Anzahl von Clients beendet wurde.
Hinweis
Anruftimeouts funktionieren nur für die ncacn_ip_tcp und ncacn_http Protokollsequenzen.