Heroku上的奇怪的TTFB(第一个字节的时间)问题

时间:2012-08-29 15:11:49

标签: ruby-on-rails performance heroku newrelic

我们正在改进我们在Heroku托管的rails应用程序的性能(rails 3.2.8和ruby 1.9.3)。在此过程中,我们遇到了一个令人担忧的问题,其源头似乎非常难以追踪。让我快速解释一下我们如何解决问题以及我们如何试图将其隔离开来。

-

自6月左右以来,我们在整个网站的Time to First Byte中经历了奇怪的滞后行为。使用该网站时显而易见的问题(有时应用程序没有响应10-20秒),并且它也通过webpagetest.org出现在瀑布分析中。 我们的总部设在丹麦,但是得到了任何主办方的结果。

为了确认问题,我们已经执行了基准测试,我们向一个简单的页面发送了300个相同的请求并测量了响应时间。 如果我们向首页发送300个请求,则中位响应时间低于1秒,这是相当不错的。令我们感到害怕的是,60个请求占用的时间增加了一倍,其中40个请求超过4秒。有些请求需要16秒。

这些慢速请求都没有出现在我们用于性能监控的New Relic中。无论我们的Web流程规模有多高,都不会显示请求排队,结果也是一样的。 尽管如此,我们还是不能拒绝问题是由应用程序代码引起的,所以我们尝试了另一个实验,我们通过机架中间件来响应请求。

通过将此中间件(TestMiddleware)放置在机架堆栈的开头,我们在它甚至命中应用程序之前返回了一个请求,确保以下任何中间件或rails应用程序都不会导致延迟。

Middleware setup:
$ heroku run rake middleware
use Rack::Cache
use ActionDispatch::Static
use TestMiddleware
use Rack::Rewrite
use Rack::Lock
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use Rack::Sendfile
use ActionDispatch::Callbacks
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::DalliStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use ActionDispatch::Head
use Rack::ConditionalGet
use Rack::ETag
use ActionDispatch::BestStandardsSupport
use NewRelic::Rack::BrowserMonitoring
use Rack::RailsExceptional
use OmniAuth::Builder
run AU::Application.routes

然后我们运行相同的脚本来记录响应时间并得到几乎相同的结果。平均响应时间是大约130MS(明显更快,因为它不&#39;。吨击中该应用,但仍60个请求了超过400个毫秒和25请求了1秒以上,再者,有些16秒钟缓慢请求< / p>

一种解释可能与网络上的慢跳或DNS设置有关,但traceroute的结果看起来非常好。

通过在Heroku上托管的另一个rails 3.2和ruby 1.9.3应用程序上运行响应脚本来确认此结果 - 完全没有奇怪的行为。

DNS设置遵循Heroku的建议。

-

至少可以说我们很困惑。 Heroku的路由网络可能会有些腥味吗? 为什么我们看到这种奇怪的行为呢?我们如何摆脱它?为什么我们不能在New Relic中看到它?

2 个答案:

答案 0 :(得分:23)

原来这是一种请求排队。有时候,那个网络服务器很忙,而且由于heroku只是随机地将传入的请求随机地路由到任何一个dyno,然后我最终可能会进入一个dyno后面的队列,因为dyno完全被卡住了。数据库问题。奇怪的是,这在新的遗物中几乎不可察觉(在他们的图表中查看所有其他资源是一个好主意,然后突然出现排队)

EDIT 21/2 2013:事实证明,它在Newrelic中难以察觉的原因是它没有被测量过! http://rapgenius.com/Lemon-money-trees-rap-genius-response-to-heroku-lyrics

我们发现这非常令人沮丧,我们最终离开了Heroku,转而使用专用服务器。这使我们的性能提高了20倍,成本的1/10。此外,我必须说我们对Heroku感到失望,他们在发生这种情况时,否认缓慢是由于他们的基础设施,即使我们怀疑并强调了几次。我们甚至得到了这样的答案:

  

Heroku 28/8 2012:“如果您没有看到New Relic中报告的请求排队或其他缓慢,那么这可能不是服务器端问题.Heroku的内部路由应该小于1毫秒。我们的监控系统目前正在指出任何路由问题。“

此外,我们采访了Newrelic,他似乎也没有意识到这个问题,即使他们根据他们自己与Heroku的工作关系非常密切。

  

Newrelic 2012年9月28日:“看起来在Ruby代理的可见性开始之前发生这种情况的原因是什么。代理记录的队列时间是从请求进入dyno的时间开始,所以减速在此之前发生。“

最重要的是,我们最终花了数小时时间来优化并非真正瓶颈的代码。另外,为了提高我们的表现,还有一个过高的dyno规模,但是我们真正得到的唯一一件事就是来自Heroku和Newrelic的更多收据 - 不是很酷。我很高兴我们改变了。

PS。当时甚至还有一个错误导致所有dynos的新手专业人员受到指控,即使我们(根据Newrelics自己的建议)已禁用对我们后台工作进程的监控。在双方承认错误之前,花了很多时间和许多电子邮件。

PPS。如果您不了解当前正在进行的讨论,那么这里是链接http://rapgenius.com/James-somers-herokus-ugly-secret-lyrics

EDIT 26/2 2013 Heroku在他们的时事通讯中只有announced,Newrelic发布了update,显然应该对Heroku的情况有所了解。

编辑2013年8月4日 Heroku刚刚发布了关于主题的FAQ

答案 1 :(得分:0)

traceroute不是网络问题的一个很好的衡量标准,它是一种可以在网络上查找故障的工具,但它不会向您显示最佳视图。

尝试放置一个静态网页,然后点击网页测试人员的IP地址。如果仍然很慢,请责怪网络。

如果出于某种原因它速度很快,那么你会遇到另外一个问题。