6

Ich habe regelmäßige, aber konsistente Latenz Spikes von meiner App auf App-Engine bemerkt. Zuerst dachte ich, dass das Netzwerk langsam sein könnte, aber App-Statistiken bestätigten, dass dies nicht der Fall ist.App Engine konsistente Latenz Spikes unter geringer Belastung

Ich habe in der Lage, die Latenz Spikes mit älteren und neueren Versionen der SDKs zu reproduzieren, ich bin derzeit die folgenden:

  • App Engine SDK: 1.9.42
  • Google Cloud Endpoints : 1.9.42
  • Objectify: 5.1.13
  • Appstats (zu Debug-Netzwerk-Latenz)

im App So Nutzung ist ziemlich l ow, in den letzten 30 Tagen bin ich in der Regel unter 0,04 Anfragen pro Sekunde:

requests per second

Die meiste Arbeit ist auch mit einer Instanz getan: enter image description here

Die meisten Operationen Latenz ist auch unter einem Zweitens, aber eine alarmierende Anzahl von Anfragen dauert 10-30x länger.

Latency density distribution

5% of requests take 23 seconds or longer...

Also habe ich es nur die Netzwerk-Latenz sein muss, aber jeder appstat eines langsameren Betrieb widerlegt dies. Datastore und das Netzwerk waren schon immer unglaublich zuverlässig. Hier ist die Anatomie einer langsamen Anfrage die Übernahme von 30 Sekunden:

app stats of operation taking 31 seconds

Hier ist die Anatomie einer normalen Anfrage: enter image description here

Auf einem hohen Niveau ist mein Code ziemlich uninteressant: Es ist ein einfach ist api, das einige Netzwerkanrufe tätigt und Daten aus dem Cloud-Datenspeicher speichert/liest. Die gesamte Quelle finden Sie unter github here. Die App wird auf einer Instanz einer Auto Scaling-App-Engine ausgeführt und ist aufgewärmt.

CPU-Auslastung im letzten Monat scheint nicht alles zu zeigen, spannend entweder: enter image description here

Es ist wirklich seltsam zu sehen, dass auch für die schnellen Operationen, ein großer Prozentsatz der Zeit auf der CPU ausgegeben wird, auch wenn der Code erstellt einfach ein paar Objekte, hält sie fest und gibt JSON zurück. Ich frage mich, ob die CPU in meiner App-Engine-Instanz von einer anderen App gebunden wird, was dazu führen kann, dass die Leistung regelmäßig beeinträchtigt wird.

Meine appengine.xml Config sieht wie folgt aus:

<?xml version="1.0" encoding="utf-8"?> 
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> 
    <application>sauce-sync</application> 
    <version>1</version> 
    <threadsafe>true</threadsafe> 
    <automatic-scaling> 
     <!-- always keep an instance up in order to keep startup time low--> 
     <min-idle-instances>1</min-idle-instances> 
    </automatic-scaling> 
</appengine-web-app> 

Und meine web.xml sieht wie folgt aus:

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5"> 
    <servlet> 
     <servlet-name>SystemServiceServlet</servlet-name> 
     <servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class> 
     <init-param> 
      <param-name>services</param-name> 
      <param-value>com.sauce.sync.SauceSyncEndpoint</param-value> 
     </init-param> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>SystemServiceServlet</servlet-name> 
     <url-pattern>/_ah/spi/*</url-pattern> 
    </servlet-mapping> 

    <!--reaper--> 
    <servlet> 
     <servlet-name>reapercron</servlet-name> 
     <servlet-class>com.sauce.sync.reaper.ReaperCronServlet</servlet-class> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>reapercron</servlet-name> 
     <url-pattern>/reapercron</url-pattern> 
    </servlet-mapping> 

    <servlet> 
     <servlet-name>reaper</servlet-name> 
     <servlet-class>com.sauce.sync.reaper.ReaperServlet</servlet-class> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>reaper</servlet-name> 
     <url-pattern>/reaper</url-pattern> 
    </servlet-mapping> 


    <welcome-file-list> 
     <welcome-file>index.html</welcome-file> 
    </welcome-file-list> 

    <filter> 
     <filter-name>ObjectifyFilter</filter-name> 
     <filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class> 
    </filter> 
    <filter-mapping> 
     <filter-name>ObjectifyFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 
</web-app> 

TLDR ich ganz fest, und ich bin nicht sicher, wie man debuggen oder beheben Sie dieses Problem und ich fange an zu denken, dass dies für kleine Apps in der App Engine wie gewohnt ist.

Ich denke darüber nach, die residente Instanz für eine Weile auszuschalten, in der Hoffnung, dass meine App gerade einige Hardware oder eine App läuft, die eine Menge Ressourcen verbraucht. Hat jemand ähnliche Leistungsprobleme oder zusätzliche Möglichkeiten zum Profilieren Ihrer App kennengelernt?

EDIT:

Ich habe am 1. residenten Instanz versucht laufe, habe ich versucht, auch gleichzeitige Anforderungen bei 2-4 per this question ohne Ergebnisse einstellen. Sowohl Logs als auch Appstats bestätigen, dass unnötig viel Zeit darauf verwendet wird, bis mein Code anfänglich ausgeführt wird. Hier ist eine Anfrage, die 25 Sekunden dauert, bevor meine erste Codezeile ausgeführt wird, nicht sicher, was die Endpunkte/App-Engine in dieser Zeit tut.

25 seconds before my code is run

Wieder Last ist nach wie vor niedrig, und dies ist Wunsch auf einer erwärmten Instanz ist.

EDIT 2:

Scheint, wie aus irgendeinem Grund App Engine + Endpunkte gut mit min-idle-instances Set spielen tut. Das Zurücksetzen auf die Standard-App-Engine-Konfiguration hat mein Problem behoben.

enter image description here

+0

möglicherweise verwandt (aber dass man unter Last gesehen wird): http://StackOverflow.com/Questions/37307461/what-can-cause-high-variability-of-untraced-time-in-app-engine-requests –

+0

Wie viele Instanzen sind normalerweise aktiv? Auch wenn Sie mindestens inaktive Instanzen auf 1 gesetzt haben, bedeutet dies nicht, dass es keine Verzögerung für neue Instanzen gibt. – BrettJ

+0

Im Allgemeinen eine Instanz, ein Diagramm mit der Anzahl der Instanzen an das Original angehängt. Ich bin mir nicht sicher, dass das viel anzeigt, aber selbst kalte Instanzen starten viel kürzer als 30 Sekunden, um eine Anfrage zu starten und abzuschließen. Es scheint wahrscheinlicher, dass die hohe Latenz zusätzliche Knoten zum Spawn veranlasst. Auch alle langsamen Anforderungen treten bei der ersten Instanz auf, da loading_request für diese langsamen Anforderungen nicht gesetzt ist. – sauce

Antwort

3

Ich habe keine Antwort, aber ich kann Ihnen einige Tipps zur Fehlerbehebung bieten.

Appstats kann oder darf nicht korrekt berichten. Protokollmeldungen werden jedoch mit Zeitstempeln versehen. Melden Sie sich nach jedem RPC-Vorgang vor & an. Das sollte dir einen Einblick geben.

30s Delays klingen ähnlich wie Aufwärmanfragen, die in den Protokollen deutlich gekennzeichnet sein sollten. Eine Sache, die ich in der Vergangenheit gefunden habe, ist, dass das Setzen von residenten Instanzen für Anwendungen mit wenig Verkehr (nicht intuitiv) dazu führte, dass viele Anfragen an kalte Instanzen weitergeleitet wurden. Verwenden Sie die Standardeinstellung und richten Sie eine Cron-Task für den Ping und den Endpunkt einmal pro Minute ein.

+0

App-Statistiken, Protokollierung und die Google-Trace-Tools auf der Cloud-Konsole haben alle bestätigten RPCs im Allgemeinen sehr schnell. Keine der langsamen Anfragen findet statt, wenn 'loading_request = 1' ist. Ich werde jedoch in Ihre anderen Vorschläge schauen, ich habe nicht versucht, zu viel mit residenten Instanzen zu basteln. PS Ich liebe Objectify :) – sauce

+0

@stickfigure Wenn es eine Warmup-Anfrage wäre, würden die RPCs nicht gegen Ende der Trace geclustert werden (wie sie nur ** genannt werden ** nachdem ** die Instanz startet)? –

+0

In der Tat nicht intuitiv, aus welchem ​​Grund auch immer funktioniert die Standard-Konfiguration am besten, obwohl Sie gelegentlich Ladeanforderungen auftreten müssen ¯ \\ _ (ツ) _/¯ – sauce