Heroku零星的高响应时间

时间:2015-03-16 22:28:17

标签: python django heroku gunicorn newrelic

这是非常具体的,但我会尽量简短:

我们正在 Heroku 上运行 Django 应用。三台服务器:

  1. test(1 web,1 celery dyno)
  2. 训练(1网,1芹菜dyno)
  3. prod(2网,1芹菜dyno)。
  4. 我们在 gevents 上使用 Gunicorn ,在每个dyno上使用 4名工作人员

    我们经历零星的高服务时间。以下是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秒超时的应用程序错误屏幕
    • 高响应时间从5000毫秒到30000毫秒不等。
    • New Relic并未指出具体问题。以下是过去的几笔交易和时间:
      • RegexURLResolver.resolve 4,270ms
      • SessionMiddleware.process_request 2,750ms
      • 渲染login.html 1,230ms
      • WSGIHandler 1,390ms
      • 以上是简单的通话,通常不会花费那么多时间

    我将其缩小为

    1. This article on Gunicorn and slow clients
      • 我看到这个问题发生在慢客户端,但也发生在我们有光纤连接的办公室。
    2. Gevent和异步工作者玩得不好
      • 我们已经切换到gunicorn同步工作者,问题仍然存在。
    3. Gunicorn工作人员超时
      • 工人可能会以某种方式在零状态下保持活着。
    4. 工人/ dynos 不足
      • 没有指示CPU /内存/ db过度使用和New Relic没有显示任何DB延迟的指示
    5. 吵闹的邻居
      • 在我与Heroku的多封电子邮件中,支持代表提到我至少有一个长期请求是由于一个吵闹的邻居,但不相信这是问题。
    6. 子域名301
      • 请求正常,但在应用程序中随机卡住。
    7. Dynos重启
      • 如果是这种情况,很多用户都会受到影响。另外,我可以看到我们的dynos最近没有重新启动。
    8. Heroku路由/服务问题
      • Heroku服务可能比宣传的要少,这只是使用他们服务的缺点。
    9. 过去几个月我们一直有这个问题,但现在我们正在扩展它需要修复。 任何想法都会非常感激,因为我已经用尽了所有SO或Google链接。

2 个答案:

答案 0 :(得分:15)

在过去的6个月里,我一直与Heroku支持团队保持联系。通过试验/错误缩短了很长一段时间,但我们已经确定了问题。

我最终注意到这些高响应时间与突然的内存交换相对应,即使我支付标准Dyno(这不是闲置),这些内存交换正在我的应用程序最近没有收到流量时发生。通过查看指标图表也可以清楚地知道这不是内存泄漏,因为内存将会停滞不前。例如:

Sudden Memory Swap

经过与支持团队的多次讨论后,我得到了这样的解释:

  

基本上,发生的事情是一些后端运行时最终会结合使用最终使用运行时必须交换的足够内存的应用程序。当发生这种情况时,运行时的一组随机dyno容器被强制任意少量交换(注意"随机"这里可能是容器内存最近没有被访问但仍然是驻留在记忆中)。与此同时,使用大量内存的应用程序最终也会大量交换,这导致运行时的iowait比正常情况更多。

     

我们还没有改变运行时间的紧密程度,因为这个问题开始变得越来越明显,所以我们目前的假设是问题可能来自客户从2.1之前的Ruby版本转移到2.1+。 Ruby弥补了我们平台上运行的应用程序的很大一部分,而Ruby 2.1对它的GC进行了更改,以便以速度换取内存使用(实质上,它不太频繁地获得速度增加)。这导致从旧版本的Ruby迁移的任何应用程序的内存使用量显着增加。因此,之前维持一定内存使用级别的相同数量的Ruby应用程序现在开始需要更多内存使用。

     

这种现象加上在平台上滥用资源的行为不当的应用程序达到了一个临界点,让我们看到了现在我们看到的不应该交换的动力的情况。我们有一些我们正在研究的攻击途径,但就目前而言,上述很多仍然有点投机。我们确实知道其中一些是由资源滥用应用程序引起的,这就是为什么迁移到Performance-M或Performance-L dynos(具有专用的后端运行时)不应该表现出问题的原因。这些dynos上唯一的内存使用量将是你的应用程序。因此,如果进行交换,那将是因为您的应用程序导致了它。

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

除了以外似乎不是一个好的解决方案 A)坚强起来等待或者等待 B)切换到其专用实例之一

我知道有人说#34;这就是你应该使用AWS"的原因,但我发现Heroku提供的好处超过了偶尔的高响应时间,并且他们的定价多年来变得更好。如果您遇到同样的问题,最好的解决方案"将是你的选择。当我听到更多内容时,我会更新这个答案。

祝你好运!

答案 1 :(得分:2)

不确定这是否会有所帮助,但我现在正在Heroku上使用Rails应用程序执行相同的操作 - 看似不确定的零星请求时间。例如,HEAD新的Relic正常运行时间ping到我的网站索引,通常需要花费5到5秒的2-5毫秒,或渲染我的网站登录,通常亚秒需要12秒。偶尔也会随机获得30秒超时。这是Heroku的支持在我的案例中所说的(至少对于某些情况而言):

  

今天早些时候看起来像重启后的一大块请求队列。如果你想避免这些,你可能想看看我们的Preboot feature。这将允许您在部署后启动匹配的一组dynos,然后将请求转交给它们,而不是踢过现有的dynos并强制请求排队。

我应该注意,这是Heroku的标准dyno重启之一,而不是我的部署或任何东西。尽管预引导页面上有警告,但我在几分钟前启用了它,所以我们会看看它是否对我的情况有所不同。希望这可能有所帮助,因为我也一直把头发拉过来!