我的用户在Heroku上偶尔会看到请求超时。不幸的是,我无法一致地重现它们,这使得它们很难调试。有很多机会提高性能 - 例如通过减少每个请求的大量数据库查询并添加更多缓存 - 但没有分析那是在黑暗中拍摄的。
根据我们的New Relic分析,许多请求在服务器上需要1到5秒。我知道这太慢了,但它还没有接近超时所需的30秒。
New Relic上的错误选项卡向我显示了几个不同的数据库查询,其中发生了超时,但这些查询并不是特别慢,并且每次崩溃都可能是不同的查询。对于相同的URL,它有时会执行,有时也不会显示数据库查询。
如何找出这些特定情况下发生的情况?例如。如何在超时发生时查看在数据库中花费的时间,而不是在没有错误时在数据库中花费的时间?
我的一个假设是数据库在某些情况下会被锁定;也许是阅读和写作的结合。
答案 0 :(得分:7)
您可能已经看过它,但Heroku有一个doc,其中有一些关于请求超时的好背景。
如果您的请求需要很长时间,并且在请求完成之前服务它们的进程没有被终止,那么它们应该生成事务跟踪,这些跟踪将提供有关单个事务的详细信息,这些事务花费的时间太长。
如果您正在使用Unicorn,则可能不会发生这种情况,因为请求花费的时间足够长,以至于他们遇到了Unicorn的timeout(之后服务这些请求的工作人员将被强行杀死,没有给New Relic代理足够的时间报告。)
我建议采用两步法:
Timeout::Error
来终止超过超时的请求,并且此类请求应在New Relic中生成事务跟踪。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 - 将准确报告等待时间测量。