Heroku时不时出现响应时间过高问题

26

这个问题比较具体,我会尽量简明地说明:

我们在Heroku上运行一个Django应用程序,有三个服务器:

  1. 测试(1个Web,1个Celery Dyno)
  2. 培训(1个Web,1个Celery Dyno)
  3. 生产(2个Web,1个Celery Dyno)

我们使用Gunicorn和gevents,在每个Dyno上有4个worker。

我们经历了零散的高服务时间。以下是来自Logentries的示例:

High Response Time:
heroku router - - at=info 
method=GET 
path="/accounts/login/" 
dyno=web.1 
connect=1ms 
service=6880ms 
status=200 
bytes=3562

我已经搜索了几周了,但我们无法复现这个问题,每天会遇到0-5次警报。注意点:

  • 所有三个应用程序上都发生(所有运行相似代码)
  • 发生在不同的页面上,包括像404和/admin这样的简单页面
  • 在随机时间发生
  • 吞吐量不同。我们的一个实例只有3个用户/天。它与睡眠dynos无关,因为我们使用New Relic进行ping测试,问题可能会在会话中发生
  • 无法随意复现。我个人经历过这个问题一次。单击通常需要500毫秒执行的页面会导致30秒的延迟,最终出现Heroku的30秒超时错误屏幕
  • 高响应时间范围为5000ms - 30000ms。
  • New Relic没有指向特定问题。以下是过去的几个交易和时间:
    • RegexURLResolver.resolve 4,270ms
    • SessionMiddleware.process_request 2,750ms
    • Render login.html 1,230ms
    • WSGIHandler 1,390ms
    • 以上是简单的调用,通常不需要那么长时间

我已经排除的问题:

  1. 这篇关于Gunicorn和慢客户端的文章
    • 我看到此问题发生在慢客户端以及我们的办公室,我们有光纤连接。
  2. Gevent和异步工作程序不友好
    • 我们已切换到gunicorn同步工作程序,但问题仍然存在。
  3. Gunicorn工作程序超时
    • 工作程序可能以空状态保持活动状态。
  4. 工人/ dynos不足
    • 没有CPU /内存/ db过度利用的迹象,New Relic也没有显示任何关于DB延迟的迹象
  5. 嘈杂的邻居
    • 在与Heroku的多封电子邮件中,支持代表提到了我的一个长请求是由于嘈杂的邻居引起的,但并不确定是否是问题的原因。
  6. 子域301
    • 请求正常通过,但随机卡在应用程序中。
  7. Dynos重新启动
    • 如果是这种情况,将影响许多用户。此外,我可以看到我们的dynos最近没有重新启动。
  8. Heroku路由/服务问题
    • 可能是Heroku服务不如宣传的那样好,这只是使用他们服务的一个缺点。

我们已经遇到了这个问题几个月了,但现在我们正在扩展它需要解决。 非常感谢任何想法,因为我几乎用尽了SO或Google的所有链接。


这似乎是一个不错的问题,但在serverfault上可能会得到更好的回答。 - jedwards
@jedwards 谢谢,但那边的一个用户评论说我应该把它移到 SO :) - grokpot
1
哦,伙计——我觉得在两个地方都有它并不是不合理的。听起来可能是一个编程或部署问题——每个网站专门处理一种情况。 - jedwards
2个回答

22

我在过去的六个月里一直与Heroku支持团队保持联系。这是一个通过试错法逐渐缩小范围的漫长过程,但我们已经确定了问题所在。

我最终注意到这些高响应时间与突然的内存交换相对应,尽管我支付的是标准Dyno(它没有闲置),但这些内存交换发生在我的应用程序最近未接收到流量时。通过查看指标图表也清楚地得知,这不是内存泄漏,因为内存会趋于稳定。例如:

突然内存交换

经过多次与他们的支持团队讨论后,我得到了以下解释:

本质上,发生的情况是一些后端运行时存在一组使用足够内存的应用程序,导致运行时必须进行交换。当这种情况发生时,随机一组Dyno容器将被迫以任意小量进行交换(注意,“随机”在这里可能是具有未被最近访问但仍驻留在内存中的内存的容器)。同时,使用大量内存的应用程序也会大规模交换,导致运行时的iowait比正常情况下更多。

自从这个问题变得越来越明显以来,我们没有改变如何紧密打包运行时,因此我们目前的假设是,问题可能来自于客户从2.1之前的Ruby版本移动到2.1+。 Ruby占了我们平台上运行的应用程序的很大比例,而Ruby 2.1对其GC进行了更改,以将内存使用量与速度进行权衡(本质上,它更不频繁地进行垃圾回收以获得速度提升)。这导致任何从旧版Ruby移动的应用程序的内存使用量显着增加。因此,维持一定内存使用水平的相同数量的Ruby应用程序现在需要更多的内存使用。

这种现象与在平台上滥用资源的应用程序相结合,达到了一个临界点,导致我们现在看到的动态进程不应该交换。我们有几个攻击途径正在研究中,但是目前上述情况仍然有些投机取巧。但我们确实知道一些资源滥用的应用程序引起了部分问题,这就是为什么转移到 Performance-M 或 Performance-L 动态进程(具有专用后端运行时)不会出现问题的原因。在这些动态进程上唯一的内存使用将是您的应用程序。因此,如果存在交换,那就是因为您的应用程序引起了它。

我确信这就是我和其他人经历过的问题,因为它与架构本身有关,而不是任何语言/框架/配置的组合。

除了 A) 坚持并等待或 B) 切换到他们的专用实例,似乎没有好的解决方案。

我知道有人说:“这就是你应该使用 AWS 的原因”,但我认为 Heroku 提供的好处超过了偶尔高响应时间,并且他们的定价在这些年里也变得更好。如果您正遭受同样的问题,“最佳解决方案”将取决于您的选择。如果我听到更多信息,我会更新这个答案。

祝你好运!


很好的发现,坚持下去!这绝对符合我在我的应用程序中看到的描述。虽然我现在还是非常高兴我使用Linode. ;) - Cade
2
我们在这个问题上和其他人一样遇到了相同的问题,我也看到了这些奇怪的交换问题。我甚至没有将两个问题联系起来,现在会保持警惕,看看是否能够发现重叠。这非常有帮助,希望现在他们承认存在这个问题后,可以解决这个问题。 - rovermicrover
刚刚检查了一下,我们的内存和延迟也有类似的模式。 - rovermicrover
感谢您发布这篇文章。我们在使用Rails堆栈时也遇到了这个问题。从经济的角度来看,转移到Performance-M实例并不是最佳方案。我们每天有几个小时的高峰期需要高性能的dyno,但其余时间两个2x dynos就足够了,通过Adept插件进行自动扩展。希望这个问题很快就会得到解决。 - kravc
是的...几年过去了,我认为这个问题还没有解决。我的一个标准1x LogEntries的URL通常在30ms内响应,但每天会有几次突然升高到30秒并触发超时。在不同项目中的一些其他Heroku应用程序中也看到了类似的结果 - 由Redis缓存支持的非常简单的API端点通常返回几毫秒,但会出现超时或接近30秒的情况。...考虑迁移到Docker Cloud部署到DigitalOcean。我不喜欢AWS的定价:( - Steve Pascoe

4

不确定这是否有所帮助,但我现在正在Heroku上使用Rails应用程序,也遇到了看似非确定性的间歇性高请求时间。例如,通常需要2-5ms才能完成对站点索引的New Relic正常运行时间ping测试,现在需要5秒钟,或者渲染我的网站登录页面,通常需要不到一秒钟的时间,现在需要12秒钟。偶尔还会出现随机的30秒超时。以下是Heroku支持团队针对我的情况(至少其中一些实例)提供的建议:

今天早些时候发生的那个情况看起来像是重新启动后的大块请求排队。如果您想避免这种情况,可以考虑使用我们的Preboot功能。这将允许您在部署后启动一组匹配的dynos,然后将请求交给它们,而不是强制关闭现有的dynos并强制请求排队。

需要说明的是,这是Heroku的标准Dyno重新启动之一,而不是我自己的部署或其他操作。尽管在preboot页面上有一些注意事项,但我几分钟前还是启用了它,看看它是否能在我的情况下产生任何变化。希望这可能会有所帮助,因为我也因此感到非常困扰!


谢谢Cade!很高兴听到我不是一个人。我们团队在部署过程中遇到了响应时间过长的问题,但我上面提到的问题并不发生在那些时候。Heroku支持团队还没有回复我。让我们保持联系,互相告知最新情况! - grokpot
目前我们的Heroku应用程序也遇到了同样的问题(Logentries警报显示高响应时间和退出超时问题)。这促使我们深入研究许多方面以尝试找出问题(在优化方面产生了积极的副作用...),但是我们无法确定什么是确定性的,什么不是(在我们的层面上)。 - Pierre
1
作为后续,我已经开启了预启动,但在周末仍收到了两个慢请求的通知。当重新访问时,加载几乎是立即完成的,但页面需要多秒钟才能加载。所以,这里仍没有答案。越来越多的情况下,我正在考虑直接放弃使用Heroku并转向AWS,因为我已经尽力调整,但问题仍无法解决。 :( - Cade
@Cade - 请确认一下:关于这个情况有任何新的信息吗?如果您已经迁移到AWS,是否仍然遇到了这个问题? - grokpot
7
我实在忍受不了了,于是我转移到了 Linode。自从四月份转移到 Linode 以来,“偶尔出现的响应缓慢问题”已经完全消失了。额外的好处是我的响应时间和应用程序性能提高了几倍,并且我支付的费用减少了78%。缺点是现在 devops 工作成了我的问题。 - Cade

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接