当前位置: 首页 > 知识库问答 >
问题:

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

满元凯
2023-03-14

从六月份左右开始,我们在整个站点上经历了奇怪的第一个字节的时间滞后行为。在使用这个站点时,问题是显而易见的(有时应用程序在10-20秒内没有响应),它也存在于通过webpagetest.org进行的瀑布分析中。我们总部设在丹麦,但从任何主持人那里得到这个结果。

为了确认问题,我们html" target="_blank">执行了一个基准测试,向一个简单页面发送300个相同的请求,并测量响应时间。如果我们向首页发送300个请求,中值响应时间在1秒以下,这是相当好的。让我们害怕的是,60个请求所需的时间是原来的两倍,其中40个请求所需的时间超过4秒。有些请求需要多达16秒。

这些缓慢的请求都不会出现在New Relic中,我们使用New Relic进行性能监视。不会出现请求队列,无论我们将web进程扩展到多高,结果都是一样的。尽管如此,我们不能否认问题是由应用程序代码引起的,所以我们尝试了另一个实验,通过机架中间件来响应请求。

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(明显更快,因为它没有击中应用程序。但仍有60个请求耗时超过400ms,25个请求耗时超过1秒。同样,有些请求慢至16秒。

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

在Heroku上的另一个Rails3.2和Ruby1.9.3应用程序上运行响应脚本证实了这个结果--没有任何奇怪的行为。

共有1个答案

马才
2023-03-14

原来这是一种请求排队。有时,web服务器很忙,由于heroku只是将随机传入的请求随机地路由到任何dyno,所以我可能会在dyno后面的队列中结束,该队列由于例如html" target="_blank">数据库问题而完全停顿。奇怪的是,这在new relic中很难被注意到(当查看图表中的thin时,取消选中所有其他资源是一个好主意,然后排队突然出现)

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

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

Newrelic 29/8 2012:“看起来,在Ruby代理的可见性开始之前,导致这种情况的原因就已经发生了。代理记录的队列时间是从请求进入dyno开始的时间,所以慢速是在此之前发生的。”

底线是,我们最终花了一个又一个小时在优化代码上,而这并不是真正的瓶颈。此外,为了提高我们的性能,我们不顾一切地使用了太高的dyno音阶,但我们真正从中得到的唯一一件事是从Heroku和Newrelic获得了更大的收入--这并不酷。我很高兴我们改变了。

当时甚至有一个bug导致newrelic pro在所有Dyno上被充电,尽管我们(根据NewAlics自己的建议)已经禁用了对后台工作进程的监控。花了很多时间,发了很多邮件,错误才被双方承认。

PPS.如果你不知道当前正在进行的讨论,那么这里是http://rapgenius.com/james-somers-herokus-bugly-secret-lyrics的链接

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

EDIT 8/4 2013 Heroku刚刚发布了一个关于这个主题的常见问题解答

 类似资料:
  • 问题内容: 我正在尝试获取价值TTFB和连接价值 它会像 但是,我只需要golang变量中value的值。 另外,有什么方法可以在不专门使用curl的情况下获取值? 问题答案: 自Go 1.7起就有对此的内置支持。Go 1.7添加了HTTP跟踪,请阅读博客文章:HTTP跟踪简介 您可以指定在发出HTTP(S)请求时在适当的阶段/点调用的回调函数。您可以通过创建值来指定回调函数,然后使用来“武装”它

  • 问题内容: 此示例取自tour.golang.org/#63 输出 为什么只打印次数而不是? 编辑: 答案可以引自golang规范: 程序执行首先初始化主程序包,然后调用函数main。当函数main返回时,程序退出。它不等待其他(非主)goroutine完成。 问题答案: 当您的主要功能结束时,程序即结束,即所有goroutine均终止。您的主体在完成之前会终止。如果您在主课程结束时睡了一段时间,

  • com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段“ID”(类com.optimight.prakash.general.employee)未标记为可忽略(0个已知属性:]),位于[源:(字符串)“{”ID“:1,”名称“:”Lokesh Gupta“,”年龄“:34,”位置“:”印度“}”;行:1,列:

  • 我无法在最简单的JSF2.2页面上使用侦听器。赋值,但监听器是聋子。奇怪的是,如果我将替换为,同样的代码工作得非常好。下面是HTML: 对于两种侦听器方法类型都不触发。将bean制作为和使用不同的ajax事件类型也无济于事。 该问题出现在Apache Tomee升级到7.0.1版本(MyFaces 2.2.10,JSF 2.2)之后。MyFaces到2.2.11也有同样的问题。 web应用程序绑定

  • 问题内容: 这是代码片段: 输出为: 为什么会这样呢?我认为是,要么,或。 这里发生了什么? 问题答案: 二是算术加法,不是字符串连接。您必须执行或之类的操作,或使用和方法来确保操作符中的至少一个是用于字符串串联的运算符。 [JLS 15.18加法运算符](http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#

  • 问题内容: 令人难以置信。为什么输出-124? 问题答案: 在Java中,an 是32位。A 是8 。 最原始的类型Java中的签名,,,,和long被编码在二进制补码。(类型为unsigned,并且sign的概念不适用于。) 在此数字方案中,最高有效位指定数字的符号。如果需要更多位,则将最高有效位(“ MSB”)简单复制到新的MSB中。 因此,如果你具有 并将其表示为 32位,则只需将1复制到左