2011-12-14 4 views
7

No he tenido mucha suerte para encontrar información en Google, tal vez alguien aquí ha tenido un problema similar.Una consulta postgres lenta en Heroku no se ve interrumpida por el tiempo de espera de rack

Tenemos una aplicación de rieles que se ejecuta en Heroku con una base de datos de Postgres. Tenemos una consulta particularmente lenta (sí, estamos trabajando para solucionar la consulta), pero en el curso de la depuración de este problema, observé que nuestra gema de tiempo de espera de rack no está matando la solicitud en 15 segundos. Hice una prueba lateral insertando un reposo (50) y, por supuesto, el tiempo de espera del rack funciona correctamente en ese caso.

Aquí hay una copia redactada de nuestros registros que muestra que el tiempo de rack (¡se acabó el tiempo!) Está sucediendo unos minutos más tarde y todavía estamos viendo H12 Request Timeout después de 30 segundos.

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]): 

¿Alguna idea de por qué y cómo aplicar el tiempo de espera del rack?

Respuesta

4

Sí, lo que está sucediendo aquí es lo que yo llamo un zombi dyno. El tiempo de espera de 30 segundos se produce en la malla de enrutamiento que se encuentra sobre su Dyno. En teoría, su dyno puede funcionar durante horas, pero el usuario verá un error después de 30 segundos directamente de la malla de enrutamiento.

So. Lo que pasa es esto:

  1. Su solicitud se hace en 21:15:16
  2. En 21:15:46 la malla de enrutamiento devuelve su error, pero el banco de pruebas todavía está procesando
  3. En 21:18:47 su solicitud de acabados.

En cuanto a qué sucede con Rack :: Timeout y su consulta de larga ejecución, tal vez hasta la joya pg su uso como Rack :: Timeout depende de que los hilos funcionen correctamente. Esto explica por qué obtienes el tiempo de espera en el momento en que la base de datos retorna.

Más información sobre dinamómetros zombi: http://neilmiddleton.com/avoiding-zombie-dynos-with-heroku/

+0

Gracias por la respuesta. Lo que estoy buscando es una idea de cómo puedo forzar el tiempo de espera del rack para cortar la solicitud. Estamos utilizando heroku y no especificamos el pg_gem, heroku lo hace. Estamos utilizando una base de datos no compartida que está en la versión 9.0.6. – sorens

+0

Desafortunadamente, Rack Timeout no puede matar una consulta en ejecución. Tu aplicación usará la gema pg en Heroku, ya que se inyecta mediante el proceso de compilación de babosas. –

1

Hasta Postgres 9.2 sale (que tiene un mejor sistema de tiempo de espera), no hay una solución fácil con la gema rack de tiempo de espera - postgres sólo comprueba la interrupción conexión entre las declaraciones y por lo tanto, el tiempo de espera del rack está algo limitado a este respecto. Sus manos están atadas ... Si tuviera acceso de superusuario a postgres, podría intentar algunos ajustes de configuración, pero como está en heroku, esa no es una opción.

Trate de optimizar sus llamadas a la base de datos (asegúrese de que todos sus índices estén allí, etc.) o desglose sus declaraciones individuales en fragmentos más pequeños para este problema específico (esto puede parecer contraintuitivo).

Cuestiones relacionadas