2013-01-17 10 views
11

Moi użytkownicy widzą sporadyczne limity czasu na żądanie na Heroku. Niestety nie mogę ich konsekwentnie odtworzyć, co sprawia, że ​​naprawdę trudno je debugować. Istnieje wiele możliwości poprawy wydajności - np. redukując ogromną liczbę zapytań do bazy danych na żądanie i dodając więcej pamięci podręcznej - ale bez profilowania to strzał w ciemność.Jak profilować niespójne limity czasu H12 na Heroku

Zgodnie z naszymi analitykami New Relic wiele żądań trwa od 1 do 5 sekund na serwerze. Wiem, że to zbyt wolno, ale nie jest to nawet 30 sekund potrzebne do przekroczenia limitu czasu.

Zakładka błędów w New Relic pokazuje mi kilka różnych zapytań do bazy danych, w których występuje przekroczenie limitu czasu, ale nie są to szczególnie powolne zapytania i mogą to być różne zapytania dotyczące każdej awarii. Również w przypadku tego samego adresu URL czasami pojawia się, a czasami nie pokazuje zapytania do bazy danych.

Jak mogę się dowiedzieć, co się dzieje w tych konkretnych przypadkach? Na przykład. jak mogę sprawdzić, ile czasu spędził w bazie danych po przekroczeniu limitu czasu, w przeciwieństwie do czasu, jaki spędza w bazie danych, gdy nie ma błędu?

Mam jedną hipotezę, że baza danych zostaje zablokowana w niektórych przypadkach; być może połączenie czytania i pisania.

+0

Przeglądałeś dzienniki?Następnym razem, gdy pojawi się problem, natychmiast przejdź do wiersza poleceń i wpisz "logi heroku". Publikowanie dzienników z błędu pomoże nam rozwiązać problem. –

+0

@BrianPetro Mam dzienniki, ale są one różne dla każdego przypadku - nawet na tej samej stronie - ponieważ cały czas kończą inne miejsce. Właśnie dlatego szukam bardziej ogólnego sposobu debugowania tego. –

+0

Zaktualizuj wpis, dodając kilka logów lub najbardziej odpowiedni kod. W przeciwnym razie obawiam się, że nie mogę pomóc. –

Odpowiedz

7

Być może już to widziałeś, ale Heroku ma doc z dobrym tłem na temat limitów czasu na żądanie.

Jeśli twoje żądania trwają długo, a procesy je obsługujące nie zostaną zabite przed zakończeniem żądań, powinny generować ślady transakcji, które będą zawierały szczegółowe informacje o poszczególnych transakcjach, które trwały zbyt długo.

Jeśli używasz Unicorn, możliwe, że tak się nie dzieje, ponieważ prośby trwają wystarczająco długo, aż trafią na Unicorn timeout (po czym pracownicy obsługujący te żądania zostaną siłą zabici, nie dając Nowy agent Relic wystarczająco długo, aby zgłosić się z powrotem).

polecam podejście dwuetapowe:

  1. skonfigurować rack-timeout middleware mieć timeout poniżej 30s Timeout Heroku użytkownika. Jeśli to zadziała, spowoduje to zakończenie żądań trwających dłużej niż limit czasu, podnosząc wartość Timeout::Error. Takie żądania powinny generować ślady transakcji w New Relic.
  2. Jeśli to nic nie daje (co może, ponieważ timeout w szafie opiera się na klasie stdlib Ruby'ego Timeout, która ma some limitations), możesz spróbować podważyć czas oczekiwania na obsługę Unicorn z domyślnego czasu 60. (zakładając, że używasz Unicorn). Pamiętaj, że długo trwające prośby będą wiązać pracownika Unicorn na dłuższy okres w tym przypadku, co może dodatkowo spowolnić działanie witryny, więc używaj jej w ostateczności.
1

Dwa lata późno. Mam minimalne doświadczenie z Ruby, ale dla Django problem z Gunicornem polega na tym, że nie obsługuje on poprawnie powolnych klientów na Heroku, ponieważ żądania nie są wstępnie buforowane, co oznacza, że ​​połączenie z serwerem może pozostać w oczekiwaniu (blokowanie). This might be a helpful article to you, chociaż dotyczy to głównie Gunicorn i Python.

Powiązane problemy