2016-10-21 16 views
6

Zauważyłem okresowe, ale spójne skoki opóźnień z mojej aplikacji działającej na silniku aplikacji. Początkowo myślałem, że sieć może działać wolno, ale statystyki aplikacji potwierdziły, że tak nie jest.Suma impulsów opóźnień w aplikacji App pod niskim obciążeniem

udało mi się odtworzyć za pomocą kolców latencji starsze i nowsze wersje SDK, obecnie używam następujące:

  • App Engine SDK: 1.9.42
  • punktów końcowych w chmurze Google : 1.9.42
  • zobiektywizować: 5.1.13
  • Appstats (do sieci debugowania latencji)

więc wykorzystanie w aplikacji jest dość l ow, w ciągu ostatnich 30 dni jestem na ogół poniżej 0,04 wniosków drugi:

requests per second

Większość prac odbywa się z jednej instancji, a także: enter image description here

Większość latency eksploatacja jest dobrze punkcie a po drugie, alarmująca liczba żądań zabiera 10-30 razy więcej czasu.

Latency density distribution

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

Więc pomyślałem, to musi po prostu być opóźnienia w sieci, ale każdy appstat z wolniejszego działania obalona to. Datastore i sieć zawsze były niesamowicie niezawodne. Oto anatomia powolne żądanie przejęcia 30 sekund:

app stats of operation taking 31 seconds

Oto anatomii normalnego żądanie: enter image description here

Na wysokim poziomie mojego kodu jest dość nieciekawe: to proste api, który wykonuje kilka połączeń sieciowych i zapisuje/odczytuje dane z magazynu danych w chmurze. Całe źródło można znaleźć pod adresem github here. Aplikacja działa na jednym egzemplarzu mechanizmu aplikacji automatycznej skalowania i jest rozgrzana.

użycie procesora w ciągu ostatniego miesiąca doesnt zdają się pokazać coś ekscytujące albo: enter image description here

To naprawdę dziwne, że nawet dla szybkich operacji, ogromny procent czasu poświęca się na CPU, chociaż kodu po prostu tworzy kilka obiektów, utrzymuje je i zwraca JSON. Zastanawiam się, czy procesor jest uzależniony od instancji mojego aparatu aplikacji przez inną aplikację, która może powodować okresowe obniżanie wydajności.

Moja appengine.xml config wygląda następująco:

<?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> 

A moja web.xml wygląda następująco:

<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 Jestem całkowicie zablokowany i nie jestem pewien, jak debugowanie lub naprawianie tego problemu i zaczynam myśleć, że jest to normalne działanie dla mniejszych aplikacji na silniku aplikacji.

Zastanawiam się, czy wyłączyć instancję rezydentną przez pewien czas, mając nadzieję, że moja aplikacja właśnie uruchomiła jakiś sprzęt piętrowy lub obok aplikacji zużywającej dużo zasobów. Czy ktoś ma podobne problemy z wydajnością lub zna dodatkowe sposoby profilowania aplikacji?

EDIT:

Próbowałem działa na 1 przykład rezydenta, ja też próbowałem ustawienie równoczesnych żądań 2-4 per this question bez rezultatów. Logi i appstats potwierdzają, że nadmierny czas spędzany jest na oczekiwaniu na mój początkowy kod. Oto prośba, która zajmuje 25 sekund przed uruchomieniem mojego pierwszego wiersza kodu, nie wiem, co robi w tym czasie punkt końcowy/silnik aplikacji.

25 seconds before my code is run

obciążenia kolei jest niski, a to żądanie jest ogrzanej przykład.

EDIT 2:

Wydaje się, bez względu na przyczynę App Engine + punkty końcowe robi grać dobrze min-idle-instances zestawie. Przywrócenie domyślnej konfiguracji silnika aplikacji naprawiło mój problem.

enter image description here

+0

potencjalnie pokrewny (ale widziany pod obciążeniem): http://stackoverflow.com/questions/37307461/what-can-cause-high-barność-of-untraced-time-in-app-engine-requests –

+0

Ile instancji jest zazwyczaj aktywnych? Nawet jeśli masz minimalną liczbę nieaktywnych instancji ustawioną na 1, nie oznacza to, że nie ma opóźnień dla nowych instancji. – BrettJ

+0

Ogólnie 1 wystąpienie, dołączony wykres z liczbą wystąpień do oryginału. Nie jestem pewien, czy to wskazuje na to, że uruchomienie nawet zimnych instancji trwa znacznie krócej niż 30 sekund, aby rozpocząć i zakończyć żądanie. Wydaje się, że większe opóźnienie powoduje pojawianie się dodatkowych węzłów. Wszystkie pierwsze powolne żądania pojawiają się w pierwszej instancji, ponieważ ładowanie_request nie jest ustawione dla tych powolnych żądań. – sauce

Odpowiedz

3

nie mam odpowiedzi, ale mogę zaoferować Ci kilka wskazówek debugowania.

Appstats może, ale nie musi zgłaszać poprawnie. Jednak komunikaty dziennika otrzymują znacznik czasu. Zaloguj się przed & po każdej operacji RPC. To powinno dać ci trochę wglądu.

Opóźnienia 30s brzmią bardzo podobnie do wniosków o rozgrzewkę, które powinny być wyraźnie oznaczone w dziennikach. Jedną z rzeczy, które udało mi się znaleźć w przeszłości, było to, że ustawienie dowolnych rezydentnych wystąpień dla aplikacji o małym natężeniu ruchu (nieintuicyjnie) powodowało kierowanie wielu żądań do zimnych instancji. Użyj domyślnego ustawienia i skonfiguruj zadanie cron na ping i punkt końcowy raz na minutę.

+0

Statystyki aplikacji, logowanie i narzędzia śledzenia Google na konsoli w chmurze potwierdziły, że wywołania RPC są generalnie bardzo szybkie. Żadne z powolnych żądań nie ma miejsca, gdy "loading_request = 1". Przyjrzę się twoim innym sugestiom, ale nie próbowałem zbytnio tinkeringować z instancjami rezydentów. PS Uwielbiam Objectify :) – sauce

+0

@przy konfigurowaniu, czy byłoby to żądanie rozgrzewania, czy RPC nie zostaną zgrupowane pod koniec śledzenia (ponieważ będą one wywoływane ** po ** uruchomieniu instancji)? –

+0

Nieintuicyjne, z jakiejkolwiek przyczyny domyślna konfiguracja działa najlepiej, chociaż od czasu do czasu będziesz musiał ponosić żądania ładowania ¯ \\ _ (ツ) _/¯ – sauce