2011-12-14 13 views
7

Nie miałem dużo szczęścia ze znalezieniem informacji przez google, może ktoś tutaj miał podobny problem.Powolne zapytanie o Postgres na Heroku nie jest przerywane przez timeout-timeout

Mamy aplikację szyny działającą na Heroku z bazą Postgres DB. Mamy szczególnie powolne zapytanie (tak, pracujemy nad poprawieniem zapytania), ale w trakcie debugowania tego problemu zauważyłem, że nasz klejnot czasu na szafę nie zabija żądania po 15 sekundach. Zrobiłem test boczny poprzez wstawienie uśpienia (50) i na pewno wystarczająco, czas oczekiwania na rack działa poprawnie w tym przypadku.

Oto zredagowana kopia naszych dzienników, która pokazuje, że czas przechowywania w szafie (czas minął!) Dzieje się kilka minut później i nadal widzimy limit czasu żądania H12 po 30 sekundach.

2011-12-14T21:15:16+00:00 app[web.2]: Started GET "/search?utf8=%E2%9C%93&terms=foo" for 173.164.186.205 at Wed Dec 14 13:15:16 -0800 2011 
    2011-12-14T21:15:16+00:00 app[web.2]: search query elapsed time => [0.000365018844604492] 
    2011-12-14T21:15:46+00:00 heroku[router]: Error H12 (Request timeout) -> GET /search dyno=web.2 queue= wait= service=30000ms status=503 bytes=0 
    2011-12-14T21:18:47+00:00 app[postgres]: [6-1] [removed] [COBALT] LOG: duration: 211241.725 ms statement: SELECT [truncated] 
    2011-12-14T21:18:47+00:00 app[web.2]: 
    2011-12-14T21:18:47+00:00 app[web.2]: ActionView::Template::Error (Timeout::Error: time's up!: SELECT [truncated]): 

Wszelkie informacje na temat tego, dlaczego i jak egzekwować limit czasu w magazynie?

Odpowiedz

4

Tak, to, co się tutaj dzieje, to to, co nazywam dyno zombie. 30-sekundowy limit czasu występuje w siatce routingu, która znajduje się nad twoją Dyno. Teoretycznie, twoja dyno może działać przez wiele godzin, ale użytkownik zobaczy błąd po 30 sekundach bezpośrednio z siatki routingu.

So. co się dzieje to:

  1. Twój wniosek został złożony w 21:15:16
  2. Na 21:15:46 siatka routingu zwraca to błąd, ale twój hamownia jest nadal przetwarzania
  3. At 21:18:47 swoimi wykończeń żądanie.

Jak dla co dzieje się z Rack :: Timeout i długiej zapytania biegu, to może do gem pg używasz jako Rack :: Czas oczekiwania jest uzależniony od nici, aby funkcjonować poprawnie. To wyjaśnia, dlaczego otrzymujesz limit czasu w chwili powrotu bazy danych.

Więcej informacji na hamowni zombie: http://neilmiddleton.com/avoiding-zombie-dynos-with-heroku/

+0

Dzięki za odpowiedź. To, czego szukam, to wgląd w to, w jaki sposób mogę zmusić program typu rack-timeout do wyłączenia tej prośby. Używamy heroku, a my nie określamy pg_gem, heroku. Używamy niewspółużytkowanej bazy danych w wersji 9.0.6. – sorens

+0

Niestety, czas oczekiwania na Rack nie może zabić uruchomionego zapytania. Twoja aplikacja będzie korzystała z gem gem na Heroku, ponieważ jest wstrzykiwany przez proces kompilacji slug. –

1

Do PostgreSQL 9.2 wychodzi (który ma lepszy system limitu czasu), nie jest to łatwe rozwiązanie z gem rack-timeout - postgres sprawdza tylko do przerwania połączenia między oświadczeń i w związku z tym czas oczekiwania na wyłączenie jest nieco ograniczony. Jego ręce są związane ... Jeśli miałbyś dostęp superużytkownika do postgresów, mógłbyś spróbować poprawić konfigurację, ale ponieważ jesteś na heroku, to nie jest opcja.

Spróbuj zoptymalizować połączenia z bazami danych (upewnij się, że są tam wszystkie indeksy itp.) Lub rozdzielić pojedyncze wypowiedzi na mniejsze fragmenty dla tego konkretnego problemu (może się to wydawać sprzeczne z intuicją).

Powiązane problemy