In vielen Fällen führt eine erhöhte Latenz in Ihrer Anwendung letztendlich zu 5xx-Serverfehlern. Da die Ursache von Fehler- und Latenzspitzen möglicherweise identisch ist, sollten Sie die folgenden Strategien zur Fehlerbehebung bei Latenzproblemen anwenden:
Latenzproblem eingrenzen
Definieren Sie den Umfang des Problems, indem Sie die folgenden Fragen stellen:
- Welche Anwendungen, Dienste und Versionen sind von diesem Problem betroffen?
- Welche spezifischen Endpunkte im Dienst sind von diesem Problem betroffen?
- Wirkt sich dies auf alle Clients weltweit oder auf eine bestimmte Teilmenge von Clients aus?
- Wie lauten Start und Ende des Vorfalls? Geben Sie die Zeitzone an.
- Welche spezifischen Fehler werden angezeigt?
- Was ist das beobachtete Latenzdelta, das normalerweise als Erhöhung bei einem bestimmten Perzentil angegeben wird? Beispiel: die Latenz war beim 90. Perzentil um 2 Sekunden erhöht.
- Wie haben Sie die Latenz gemessen? Haben Sie die Anfrage insbesondere auf dem Client gemessen oder ist sie in Cloud Logging oder in den Cloud Monitoring-Latenzdaten sichtbar, die von der App Engine-Bereitstellungsinfrastruktur bereitgestellt werden?
- Welche Abhängigkeiten hat Ihr Dienst und hat es Vorfälle mit diesen gegeben?
- Haben Sie kürzlich Code-, Konfigurations- oder Arbeitslaständerungen vorgenommen, die dieses Problem ausgelöst haben könnten?
Ein Dienst kann über ein eigenes benutzerdefiniertes Monitoring und Logging verfügen, mit dem Sie den Problembereich weiter eingrenzen können. Wenn Sie den Umfang des Problems eingrenzen, werden Sie zur wahrscheinlichen Ursache geführt und können die nächsten Schritte zur Fehlerbehebung ermitteln.
Ursache ermitteln
Bestimmen Sie, welche Komponente im Anfragepfad am wahrscheinlichsten die Latenz oder Fehler verursacht. Die Hauptkomponenten im Anfragepfad sind:
Client --> Internet --> Google Front End (GFE) --> App Engine-Bereitstellungsinfrastruktur --> Dienstinstanz
Wenn die vorherigen Informationen nicht auf die Fehlerquelle verweisen, wenden Sie die folgenden Strategien an, während Sie den Zustand und die Leistung Ihrer Dienstinstanz prüfen:
App Engine-Anfragelogs überwachen Wenn Sie HTTP-Statuscodefehler oder eine erhöhte Latenz in diesen Logs sehen, liegt das Problem wahrscheinlich bei der Instanz, auf der Ihr Dienst ausgeführt wird.
Wenn die Anzahl der Dienstinstanzen nicht an das Traffic-Niveau angepasst wurde, sind Ihre Instanzen möglicherweise überlastet, was zu mehr Fehlern und einer höheren Latenz führt.
Wenn in Cloud Monitoring häufige Fehler oder hohe Latenz auftreten, liegt das Problem möglicherweise vor dem Load-Balancer, der die App Engine-Messwerte aufzeichnet. In den meisten Fällen weist dies auf ein Problem in den Dienstinstanzen hin.
Wenn Sie in den Monitoring-Messwerten eine erhöhte Latenz oder häufige Fehler sehen, aber nicht in den Anfragelogs, deutet dies entweder auf einen Load-Balancing-Fehler oder einen schwerwiegenden Instanzfehler hin, der verhindert, dass der Load-Balancer Anfragen weiterleitet. Um zwischen diesen Fällen zu unterscheiden, sehen Sie sich die Anfragelogs vor dem Beginn des Vorfalls an. Wenn die Anfragelogs vor dem Fehler eine zunehmende Latenz zeigen, bedeutet dies, dass die Anwendungsinstanzen selbst versagen, bevor der Load-Balancer keine Anfragen mehr an sie weiterleitet.
Fehlerbehebung
In diesem Abschnitt werden Strategien zur Fehlerbehebung bei Problemen mit erhöhter Latenz der folgenden Komponenten im Anfragepfad beschrieben:
- Internet
- Google Front End (GFE)
- App Engine-Bereitstellungsinfrastruktur
- Anwendungsinstanz
- Anwendungsabhängigkeiten
Internet
In Ihrer Anwendung können aufgrund einer schlechten Verbindung oder einer geringeren Bandbreite Latenzprobleme auftreten.
Schlechte Internetverbindung
Führen Sie den folgenden Befehl auf Ihrem Client aus, um festzustellen, ob das Problem eine schlechte Internetverbindung ist:
$ curl -s -o /dev/null -w '%{time_connect}\n' <hostname>
Der Wert für time_connect gibt die Latenz der Verbindung des Clients zum nächsten Google Front End an.
Bei langsamen Verbindungen können Sie mithilfe von traceroute weitere Fehler beheben, um festzustellen, welcher Hop im Netzwerk die Verzögerung verursacht.
Tests von Clients an verschiedenen geografischen Standorten ausführen App Engine leitet Anfragen automatisch an das nächstgelegene Google-Rechenzentrum weiter, was je nach Standort des Clients variiert.
Niedrige Bandbreite
Die Anwendung reagiert möglicherweise schnell, aber Netzwerkengpässe verzögern das Senden von Paketen über das Netzwerk durch die App Engine-Bereitstellungsinfrastruktur, wodurch Antworten verlangsamt werden.
Google Front End (GFE)
In Ihrer Anwendung können Latenzprobleme aufgrund von falschem Routing, parallelen Anfragen von HTTP/2-Clients oder der Beendigung von SSL-Verbindungen auftreten.
Client-IP einer geografischen Region zuordnen
Google löst den Hostnamen der App Engine-Anwendung zum nächstgelegenen GFE zum Client auf, basierend auf der Client-IP-Adresse, die bei der DNS-Suche verwendet wird. Wenn der DNS-Resolver des Clients nicht das EDNS0-Protokoll verwendet, werden Clientanfragen möglicherweise nicht an das nächstgelegene GFE weitergeleitet.
HTTP/2-Head-of-Line-Blocking
HTTP/2-Clients, die mehrere Anfragen parallel senden, können aufgrund des Head-of-Line-Blockings im GFE eine erhöhte Latenz aufweisen. Um dieses Problem zu beheben, müssen die Clients das QUIC-Protokoll verwenden.
SSL-Terminierung für benutzerdefinierte Domains
Das GFE beendet möglicherweise die SSL-Verbindung. Wenn Sie eine benutzerdefinierte Domain anstelle einer appspot.com-Domain verwenden, ist für die SSL-Terminierung ein zusätzlicher Hop erforderlich. Dies kann zu Latenzen bei Anwendungen führen, die in einigen Regionen ausgeführt werden. Weitere Informationen finden Sie unter Benutzerdefinierte Domains zuordnen.
App Engine-Bereitstellungsinfrastruktur
In Ihrer Anwendung kann es aufgrund von dienstweiten Vorfällen oder der automatischen Skalierung zu einer erhöhten Latenz kommen.
Dienstweite Vorfälle
Google veröffentlicht Details zu schwerwiegenden dienstweiten Problemen im Dashboard Dienststatus. Google führt jedoch schrittweise Rollouts durch, sodass ein dienstweiter Vorfall wahrscheinlich nicht alle Instanzen gleichzeitig betrifft.
Autoscaling
Die folgenden Autoscaling-Szenarien können zu erhöhten Latenzzeiten oder Fehlern führen:
Traffic zu schnell hochskaliert: Beim App Engine-Autoscaling werden Ihre Instanzen möglicherweise nicht so schnell skaliert, wie der Traffic zunimmt, was zu einer vorübergehenden Überlastung führt. In der Regel geschieht dies, wenn der Traffic nicht von Endnutzern, sondern von einem Computerprogramm generiert wird. Um dieses Problem zu beheben, drosseln Sie das System, das den Traffic generiert.
Trafficspitzen: Trafficspitzen können zu einer höheren Latenz führen, wenn ein automatisch skalierter Dienst schneller hochskaliert werden muss, als es ohne Beeinträchtigung der Latenz möglich ist. Endnutzer-Traffic verursacht in der Regel keine häufigen Trafficspitzen. Wenn Sie Trafficspitzen sehen, sollten Sie die Ursache untersuchen. Wenn ein Batchsystem in Intervallen ausgeführt wird, können Sie den Traffic möglicherweise ausgleichen oder andere Skalierungseinstellungen verwenden.
Autoscaler-Einstellungen: Der Autoscaler kann anhand der Skalierungsmerkmale Ihres Dienstes konfiguriert werden. Die Skalierungsparameter können sich in den folgenden Szenarien ungünstig entwickeln:
Die Skalierungseinstellungen der App Engine-Standardumgebung können zu Latenzen führen, wenn sie zu aggressiv festgelegt sind. Wenn Sie in Ihren Logs Serverantworten mit dem Statuscode
500und der Nachricht „Request was aborted after waiting too long to attempt to service your request“ (Anfrage wurde abgebrochen, da zu lange gewartet wurde, bis die Anfrage bearbeitet werden konnte) sehen, wurde das Zeitlimit überschritten, während die Anfrage in der Warteschlange auf eine freie Instanz wartete.Bei manueller Skalierung kann es zu längeren Wartezeiten kommen, auch wenn Sie genügend Instanzen bereitgestellt haben. Wir empfehlen, manuelle Skalierung nicht zu verwenden, wenn Ihre Anwendung Endnutzertraffic verarbeitet. Die manuelle Skalierung ist besser für Arbeitslasten wie Aufgabenwarteschlangen.
Bei der einfachen Skalierung werden die Kosten auf Kosten der Latenz minimiert. Wir empfehlen, einfache Skalierung nicht für latenzempfindliche Dienste zu verwenden.
Die Standardskalierungseinstellung von App Engine bietet eine optimale Latenz für die meisten Dienste. Wenn Sie weiterhin Anfragen mit hoher Wartezeit sehen, geben Sie eine Mindestanzahl von Instanzen an. Wenn Sie die Skalierungseinstellungen zur Minimierung der Kosten optimieren, indem Sie inaktive Instanzen minimieren, besteht die Gefahr, dass Latenzspitzen auftreten, wenn die Last plötzlich ansteigt.
Wir empfehlen Ihnen, die Leistung mit den Standardskalierungseinstellungen zu vergleichen und nach jeder Änderung an diesen Einstellungen eine neue Benchmark auszuführen.
Bereitstellungen
Eine erhöhte Latenz kurz nach einer Bereitstellung gibt an, dass Sie vor der Migration des Traffics nicht ausreichend vertikal skaliert haben. Bei neueren Instanzen sind möglicherweise keine lokalen Caches vorbereitet, sodass sie langsamer ausgeführt werden als ältere Instanzen.
Stellen Sie keinen App Engine-Dienst bereit, der denselben Versionsnamen wie eine vorhandene Version des Dienstes verwendet, um Latenzspitzen zu vermeiden. Wenn Sie einen vorhandenen Versionsnamen wiederverwenden, können Sie den Traffic nicht langsam zur neuen Version migrieren. Anfragen können langsamer sein, da App Engine jede Instanz innerhalb kurzer Zeit neu startet. Sie müssen die Bereitstellung auch noch einmal ausführen, wenn Sie zur vorherigen Version zurückkehren möchten.
Anwendungsinstanz
In diesem Abschnitt werden die gängigen Strategien beschrieben, die Sie auf Ihre Anwendungsinstanzen und Ihren Quellcode anwenden können, um die Leistung zu optimieren und die Latenz zu verringern.
Anwendungscode
Probleme im Anwendungscode können schwierig zu debuggen sein, insbesondere wenn sie zeitweise auftreten oder nicht reproduzierbar sind.
So beheben Sie Probleme:
Zur Diagnose von Problemen empfehlen wir, Ihre Anwendung mit Logging, Monitoring und Tracing zu instrumentieren. Sie können auch Cloud Profiler verwenden.
Versuchen Sie, das Problem in einer lokalen Entwicklungsumgebung zu reproduzieren. Dadurch können Sie sprachspezifische Debugging-Tools ausführen, die möglicherweise nicht in App Engine ausgeführt werden können.
Damit Sie besser verstehen, warum Ihre Anwendung fehlschlägt und welche Engpässe auftreten, können Sie einen Lasttest Ihrer Anwendung ausführen, bis ein Fehler auftritt. Legen Sie eine maximale Anzahl von Instanzen fest und erhöhen Sie dann die Last nach und nach, bis die Anwendung fehlschlägt.
Wenn das Latenzproblem mit der Bereitstellung einer neuen Version Ihres Anwendungscodes korreliert, führen Sie ein Rollback durch, um festzustellen, ob die neue Version den Vorfall verursacht hat. Bei einer kontinuierlichen Bereitstellung kann die Häufigkeit der Bereitstellungen so groß sein, dass es schwierig ist, basierend auf der Zeit des Auftretens festzustellen, ob die Bereitstellung den Vorfall verursacht hat.
Ihre Anwendung kann Konfigurationseinstellungen in Datastore oder an einem anderen Ort speichern. Erstellen Sie eine Zeitachse mit Konfigurationsänderungen, um zu bestimmen, ob eine dieser Zeilen mit dem erhöhten Latenzwert übereinstimmt.
Arbeitslaständerung
Eine Änderung der Arbeitslast kann zu einer erhöhten Latenz führen. Einige Monitoring-Messwerte, die darauf hinweisen können, dass sich die Arbeitslast geändert hat, umfassen qps, die API-Nutzung und die Latenz. Prüfen Sie auch auf Änderungen bei Anfrage- und Antwortgrößen.
Arbeitsspeicherdruck
Wenn das Monitoring entweder ein Sägezahnmuster in der Speichernutzung oder einen Rückgang der Speichernutzung zeigt, der mit Bereitstellungen korreliert, kann ein Speicherleck die Ursache für Leistungsprobleme sein. Ein Speicherleck kann auch zu einer häufigen automatischen Speicherbereinigung führen, was zu einer höheren Latenz führt. Wenn Sie das Problem nicht auf ein Problem im Code zurückführen können, versuchen Sie, größere Instanzen mit mehr Speicher bereitzustellen.
Ressourcenleck
Wenn eine Instanz Ihrer Anwendung eine zunehmende Latenz aufweist, die mit dem Alter der Instanz korreliert, kann dies an einem Ressourcenleck liegen, das zu Leistungsproblemen führt. Die Latenz sinkt, nachdem eine Bereitstellung abgeschlossen ist. Beispielsweise kann eine Datenstruktur, die aufgrund einer höheren CPU-Auslastung im Laufe der Zeit langsamer wird, dazu führen, dass jede CPU-gebundene Arbeitslast langsamer wird.
Codeoptimierung
So können Sie die Latenz in App Engine reduzieren:
Offline-Arbeit: Verwenden Sie Cloud Tasks, damit Nutzeranfragen nicht auf den Abschluss von Arbeitslasten wie dem Senden von E-Mails warten.
Asynchrone API-Aufrufe: Achten Sie darauf, dass Ihr Code nicht blockiert wird, bis ein API-Aufruf abgeschlossen ist.
Batch-API-Aufrufe: Die Batch-Version von API-Aufrufen ist normalerweise schneller als das Senden einzelner Aufrufe.
Datenmodelle denormalisieren: Reduzieren Sie die Latenz von Aufrufen an die Datenpersistenzebene, indem Sie Ihre Datenmodelle denormalisieren.
Anwendungsabhängigkeiten
Sie können Abhängigkeiten Ihrer Anwendung überwachen, um zu erkennen, ob Latenzspitzen mit einem Abhängigkeitsfehler korrelieren.
Eine Änderung der Arbeitslast und ein Anstieg des Traffics können zu einer Erhöhung der Latenz einer Abhängigkeit führen.
Nicht skalierende Abhängigkeit
Wenn die Abhängigkeit Ihrer Anwendung nicht skaliert wird, wenn die Anzahl der App Engine-Instanzen vertikal skaliert wird, kann die Abhängigkeit überlastet werden, wenn der Traffic zunimmt. Ein Beispiel für eine Abhängigkeit, die möglicherweise nicht skaliert wird, ist eine SQL-Datenbank. Eine höhere Anzahl von Anwendungsinstanzen führt zu einer höheren Anzahl von Datenbankverbindungen, was zu kaskadierenden Fehlern führen kann, da der Start der Datenbank verhindert wird. So beheben Sie das Problem:
- Eine neue Standardversion bereitstellen, die keine Verbindung zur Datenbank herstellt.
- Vorherige Standardversion abschalten.
- Eine neue, nicht standardmäßige Version bereitstellen, die eine Verbindung zur Datenbank herstellt.
- Nach und nach Traffic zur neuen Version migrieren.
Als vorbeugende Maßnahme sollten Sie Ihre Anwendung so entwerfen, dass Anfragen an die Abhängigkeit mithilfe von adaptivem Throttling gesendet werden.
Ausfall der Caching-Ebene
Um Anfragen zu beschleunigen, verwenden Sie mehrere Caching-Ebenen wie Edge-Caching, Memcache und In-Instance-Arbeitsspeicher. Ein Fehler in einer dieser Caching-Ebenen kann zu einem plötzlichen Anstieg der Latenz führen. Ein Memcache-Flush kann beispielsweise dazu führen, dass mehr Anfragen an einen langsameren Datastore gesendet werden.