关于Heroku的慢速postgres查询不会被机架超时中断

时间:2011-12-14 22:19:55

标签: ruby-on-rails-3 postgresql heroku rack

我没有太多运气通过谷歌查找信息,也许这里有人有类似的问题。

我们有一个使用Postgres DB在Heroku上运行的rails应用程序。我们有一个特别慢的查询(是的,我们正在努力修复查询),但在调试这个问题的过程中,我发现我们的机架超时gem并没有在15秒内终止请求。我已经通过插入睡眠(50)进行了侧面测试,果然,在这种情况下,机架超时工作正常。

以下是我们日志的编辑副本,显示机架时间(时间到了!)几分钟后发生,我们仍然在30秒后看到H12请求超时。

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

了解为何以及如何强制执行机架超时?

2 个答案:

答案 0 :(得分:4)

是的,这里发生的事情就是我所谓的僵尸动态。 30秒的超时是在位于Dyno上方的路由网格中发生的。从理论上讲,你的dyno可以运行几个小时,但用户将在30秒后直接从路由网格中看到错误。

因此。发生了什么事:

  1. 您的请求是21:15:16
  2. 21:15:46路由网格返回错误,但您的dyno仍在处理
  3. 21:18:47您的请求完成。
  4. 至于Rack :: Timeout和你长时间运行的查询发生了什么,它可能是你使用的pg gem,因为Rack :: Timeout依赖于线程正常运行。这解释了为什么在数据库返回时获得超时的原因。

    有关zombie dynos的更多信息:http://neilmiddleton.com/avoiding-zombie-dynos-with-heroku/

答案 1 :(得分:1)

直到postgres 9.2出来(具有更好的超时系统),没有一个简单的机架超时gem解决方案 - postgres只检查语句之间的连接中断,因此机架超时在这方面有些限制。它的双手被捆绑...如果你有超级用户访问postgres你可能会尝试一些配置调整,但因为你在heroku,这不是一个选项。

尝试优化数据库调用(确保所有索引都在那里等),或者将单个语句分解为针对此特定问题的较小块(这看起来可能违反直觉)。