22

我们正在改进托管在 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

然后我们运行相同的脚本来记录响应时间并得到几乎相同的结果。中位响应时间约为 130 毫秒(显然更快,因为它不会影响应用程序。但仍然有 60 个请求花费了 400 毫秒以上,25 个请求花费了 1 秒以上。同样,有些请求慢到 16 秒。

一种解释可能与网络上的慢跳或 DNS 设置有关,但 traceroute 的结果看起来完全没问题。

这个结果通过在 Heroku 上托管的另一个 rails 3.2 和 ruby​​ 1.9.3 应用程序上运行响应脚本得到证实——根本没有奇怪的行为。

DNS 设置遵循 Heroku 的建议。

--

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

4

2 回答 2

24

原来这是一种请求排队。有时,该 Web 服务器很忙,并且由于 heroku 只是将随机传入的请求随机路由到任何测功机,所以我最终可能会排在测功机后面的队列中,这由于例如数据库问题而完全卡住了。奇怪的是,这在新文物中几乎不明显(在他们的图表中查看薄的时候取消选中所有其他资源是个好主意,然后排队突然出现)

2013 年 2 月 21 日编辑:事实证明,它在 Newrelic 中几乎不引人注目的原因是,它没有被测量!http://rapgenius.com/Lemon-money-trees-rap-genius-response-to-heroku-lyrics

我们觉得这非常令人沮丧,最终我们放弃了 Heroku,转而使用专用服务器。这以 1/10 的成本为我们带来了 20 倍的性能提升。此外,我必须说,我们对 Heroku 感到失望,当时 Heroku 否认了缓慢是由于他们的基础设施造成的,尽管我们怀疑并多次强调了这一点。我们甚至得到了这样的答案:

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

此外,我们采访了 Newrelic,他似乎也没有意识到这个问题,尽管他们自称与 Heroku 有着非常密切的工作关系。

Newrelic 2012 年 8 月 29 日:“看起来在 Ruby 代理的可见性开始之前导致这种情况发生的任何原因。代理记录的排队时间是从请求进入测功机的时间开始的,因此在此之前发生了减速。”

底线是,我们最终花费数小时优化并非真正瓶颈的代码。此外,为了提高我们的性能,我们使用过高的测功机规模运行,但我们真正从中得到的唯一好处是 Heroku 和 Newrelic 的收益更大——这并不酷。我很高兴我们改变了。

PS。当时甚至有一个错误导致 newrelic pro 对所有测功机收费,尽管我们(根据 Newrelics 自己的建议)已经禁用了对我们后台工作进程的监控。在双方承认错误之前花了很多时间和许多电子邮件。

聚苯乙烯。如果您不知道当前正在进行的讨论,那么这里是链接http://rapgenius.com/James-somers-herokus-ugly-secret-lyrics

编辑 2013 年 2 月 26 日 Heroku 刚刚在他们的时事通讯中宣布,Newrelic 发布了一个更新,显然应该对 Heroku 的情况有所了解。

编辑 2013 年 8 月4 日 Heroku 刚刚发布了关于该主题的常见问题解答

于 2012-10-31T09:09:11.190 回答
0

traceroute 不是衡量网络问题的好方法,它是一个可以发现网络故障的工具,但它不会向您展示最佳视图。

尝试只放置一个静态网页,然后使用网页测试仪的 IP 地址点击它。如果还是慢,那就怪网络了。

如果由于某种原因它很快,那么你有一个不同的问题。

于 2012-10-28T23:15:49.237 回答