如何在Heroku上分析不一致的H12超时

时间:2013-01-17 10:34:50

标签: ruby-on-rails performance heroku newrelic

我的用户在Heroku上偶尔会看到请求超时。不幸的是,我无法一致地重现它们,这使得它们很难调试。有很多机会提高性能 - 例如通过减少每个请求的大量数据库查询并添加更多缓存 - 但没有分析那是在黑暗中拍摄的。

根据我们的New Relic分析,许多请求在服务器上需要1到5秒。我知道这太慢了,但它还没有接近超时所需的30秒。

New Relic上的错误选项卡向我显示了几个不同的数据库查询,其中发生了超时,但这些查询并不是特别慢,并且每次崩溃都可能是不同的查询。对于相同的URL,它有时会执行,有时也不会显示数据库查询。

如何找出这些特定情况下发生的情况?例如。如何在超时发生时查看在数据库中花费的时间,而不是在没有错误时在数据库中花费的时间?

我的一个假设是数据库在某些情况下会被锁定;也许是阅读和写作的结合。

3 个答案:

答案 0 :(得分:7)

您可能已经看过它,但Heroku有一个doc,其中有一些关于请求超时的好背景。

如果您的请求需要很长时间,并且在请求完成之前服务它们的进程没有被终止,那么它们应该生成事务跟踪,这些跟踪将提供有关单个事务的详细信息,这些事务花费的时间太长。

如果您正在使用Unicorn,则可能不会发生这种情况,因为请求花费的时间足够长,以至于他们遇到了Unicorn的timeout(之后服务这些请求的工作人员将被强行杀死,没有给New Relic代理足够的时间报告。)

我建议采用两步法:

  1. rack-timeout中间件配置为超出Heroku 30秒超时的超时时间。如果这样做,它将通过引发Timeout::Error来终止超过超时的请求,并且此类请求应在New Relic中生成事务跟踪。
  2. 如果没有产生任何结果(可能因为Rack-timeout依赖于Ruby的stdlib Timeout类,它有some limitations),你可以尝试将Unicorn请求处理超时从默认值60年代(假设您使用的是Unicorn)。请注意,长时间运行的请求会在这种情况下将Unicorn工作人员占用更长的时间,这可能会进一步减慢您的网站速度,因此请将此作为最后的手段。

答案 1 :(得分:1)

这里晚了两年。我对Ruby的经验很少,但对于Django来说,Gunicorn的问题在于它没有正确处理Heroku上的慢速客户端,因为请求没有预先缓冲,这意味着服务器连接可能会等待(阻塞)。 This might be a helpful article to you,虽然它主要适用于Gunicorn和Python。

答案 2 :(得分:0)

你很清楚地遇到长时间运行请求的问题。查看http://artsy.github.com/blog/2013/02/17/impact-of-heroku-routing-mesh-and-random-routing/并升级到NewRelic RPM 3.5.7.59 - 将准确报告等待时间测量。