Heroku 零星的高响应时间

Heroku Sporadic High Response Time

这很具体,但我会尽量简短:

我们是 运行 Django 应用 Heroku。三台服务器:

  1. 测试(1 个网络,1 个芹​​菜测功机)
  2. 训练(1 个网络,1 个 celery dyno)
  3. prod(2 个网络,1 个芹​​菜测功机)。

我们正在使用 Gunicorngevents,每个 dyno4 名工人

我们 遇到零星的高服务时间 。这是来自 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 次这些警报。 要点:

我将其缩小到

  1. This article on Gunicorn and slow clients
    • 我已经看到这个问题发生在速度较慢的客户端上,但也发生在我们有光纤连接的办公室。
  2. Gevent 和 async workers 表现不佳
    • 我们已经切换到 gunicorn sync workers,问题仍然存在。
  3. Gunicorn worker 超时
    • 有可能工作人员以某种方式在空状态下保持活动状态。
  4. 工人/测功机不足
    • 没有迹象表明 CPU/memory/db 过度使用并且 New Relic 没有显示任何数据库延迟迹象
  5. 吵闹的邻居
    • 在我与 Heroku 的多封电子邮件中,支持代表提到我的长请求中至少有一封是由于邻居吵闹,但不认为这是问题所在。
  6. 子域 301
    • 请求顺利通过,但在应用程序中随机卡住。
  7. Dynos 重新启动
    • 如果是这样的话,很多用户都会受到影响。另外,我可以看到我们的dynos最近没有重新启动。
  8. Heroku 路由/服务问题
    • Heroku 服务可能比宣传的要少,这只是使用他们的服务的一个缺点。

过去几个月我们一直遇到这个问题,但现在我们正在扩展它需要解决它。 任何想法将不胜感激 因为我已经用尽了几乎所有的 SO 或 Google link.

不确定这是否会有所帮助,但我现在正在 Heroku 上使用 Rails 应用程序进行同样的操作 - 看似不确定的零星请求时间。例如,HEAD New Relic 正常运行时间 ping 我的站点索引通常需要 2-5 毫秒,需要 5 秒,或者呈现我的站点登录,这通常需要 12 秒的亚秒级。偶尔也会出现随机的 30 秒超时。以下是 Heroku 的支持在我的案例中不得不说的(至少对于某些情况):

The one earlier today looks like a big chunk of Request Queueing following a restart. If you want to avoid those, you might want to take a look at our Preboot feature. This will allow you to boot up a matched set of dynos after a deployment, then turn requests over to them instead of kicking over the existing dynos and forcing the request queueing.

我应该注意,这是 Heroku 的标准 dyno 重启之一,而不是我的部署或其他任何东西。尽管预引导页面上有警告,但我在几分钟前启用了它,所以我们会看看它是否对我的情况有任何影响。希望这可能会有所帮助,因为我也一直在努力解决这个问题!

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

我最终注意到这些高响应时间与突然的内存交换相对应,即使我购买了 Standard Dyno(没有闲置),这些内存交换也是在我的应用最近没有收到流量时发生的.通过查看指标图表也可以清楚地看出这不是内存泄漏,因为内存会稳定下来。例如:

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

Essentially, what happens is some backend runtimes end up with a combination of applications that end up using enough memory that the runtime has to swap. When that happens, a random set of dyno containers on the runtime are forced to swap arbitrarily by small amounts (note that "random" here is likely containers with memory that hasn't been accessed recently but is still resident in memory). At the same time, the apps that are using large amounts of memory also end up swapping heavily, which causes more iowait on the runtime than normal.

We haven't changed how tightly we pack runtimes at all since this issue started becoming more apparent, so our current hypothesis is that the issue may be coming from customers moving from versions of Ruby prior to 2.1 to 2.1+. Ruby makes up for a huge percentage of the applications that run on our platform and Ruby 2.1 made changes to it's GC that trades memory usage for speed (essentially, it GCs less frequently to get speed gains). This results in a notable increase in memory usage for any application moving from older versions of Ruby. As such, the same number of Ruby apps that maintained a certain memory usage level before would now start requiring more memory usage.

That phenomenon combined with misbehaving applications that have resource abuse on the platform hit a tipping point that got us to the situation we see now where dynos that shouldn't be swapping are. We have a few avenues of attack we're looking into, but for now a lot of the above is still a little bit speculative. We do know for sure that some of this is being caused by resource abusive applications though and that's why moving to Performance-M or Performance-L dynos (which have dedicated backend runtimes) shouldn't exhibit the problem. The only memory usage on those dynos will be your application's. So, if there's swap it'll be because your application is causing it.

我相信这是我和其他人一直遇到的问题,因为它与架构本身有关,与 language/framework/configs 的任何组合无关。

除了 A)坚强起来等待它结束或者 B)切换到他们的专用实例之一

我知道很多人说“这就是你应该使用 AWS 的原因”,但我发现 Heroku 提供的好处超过了一些偶尔的高响应时间,而且它们的定价多年来也越来越好。如果您遇到同样的问题,“最佳解决方案”将是您的选择。当我听到更多消息时,我会更新这个答案。

祝你好运!