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

Sjo*_*ost 11 performance ruby-on-rails heroku newrelic

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

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

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

我怎样才能知道这些特殊情况下发生了什么?例如,如何在超时发生时查看在数据库中花费的时间,而不是在没有错误时在数据库中花费的时间?

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

gru*_*ler 7

您可能已经看过它了,但是Heroku有一个关于请求超时的文档.

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

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

我建议采用两步法:

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


dB.*_*dB. 0

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