11

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

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

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

我如何找出在这些特殊情况下发生了什么?例如,我如何查看发生超时时它在数据库中花费了多少时间,而不是在没有错误时它在数据库中花费的时间?

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

4

3 回答 3

7

你可能已经看过了,但是 Heroku 有一个文档,它有一些关于请求超时的良好背景。

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

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

我建议采用两步法:

  1. 将rack-timeout中间件配置为低于 Heroku 的 30 秒超时。如果这可行,它将通过引发 a 来终止花费超过超时时间的Timeout::Error请求,并且此类请求应在 New Relic 中生成事务跟踪。
  2. 如果这没有产生任何结果(它可能,因为 rack-timeout 依赖于 Ruby 的 stdlibTimeout类,它有一些限制),您可以尝试将 Unicorn 请求处理超时从其默认值 60 秒(假设您使用的是 Unicorn)。请注意,在这种情况下,长时间运行的请求会使 Unicorn 工作人员占用更长的时间,这可能会进一步降低您的站点速度,因此请将此作为最后的手段。
于 2013-04-09T05:43:44.230 回答
1

在这里晚了两年。我对 Ruby 的经验很少,但对于 Django,Gunicorn 的问题是它不能正确处理 Heroku 上的慢速客户端,因为请求没有预先缓冲,这意味着服务器连接可能会等待(阻塞)。这可能对您很有帮助,尽管它主要适用于 Gunicorn 和 Python。

于 2015-03-10T22:29:04.980 回答
0

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

于 2013-02-21T06:21:25.523 回答