2

我是 Rails 新手,刚刚将我的第一个应用程序部署到 Heroku(在免费层)。我设置了 New Relic 的免费试用版,并将可用性监控设置为每 1 分钟 ping 我的 /register/ URL。我正在运行 Rails 3.2.13 和 Ruby 1.9.3。

我的应用程序基本上没有用户,也没有请求(每分钟 2 个请求,主要来自 NewRelic)。我没有后台服务或外部依赖项。数据模型很简单,没有任何查询花费超过 100 毫秒。

我每隔几个小时就会完全中断 15 分钟。

在此处输入图像描述

由于 Heroku 只保留 1500 行日志,我没有每个事件的数据,但这是第二个 blip 的日志(我的图表是 -0400,Heroku 是 UTC)。

完整日志: https ://gist.github.com/jbinto/5495226/raw/ba61ec16d9655287466cfbb9328f59c0171b2df7/heroku.log

概括

  • 00:56:21 到 01:00:21:正常情况下每分钟发出 1 个请求。
  • 01:01:55:最后一个请求,似乎没有得到满足。
  • 01:02:21 到 01:17:21: 54 H12(请求超时)错误。
  • 01:17:25: PG::Error(SSL SYSCALL 错误:检测到 EOF) (另外:我注意到 Heroku 的日志语句有问题,很奇怪。)

这个 PG::Error 是我的问题的原因,还是仅仅是一个症状?一些谷歌搜索显示了关于起始层上 Postgres 超时的讨论,以及一些不使用生产层的警告: https ://groups.google.com/forum/?fromgroups=#!topic/heroku/a6iviwAFgdY

更多 StackOverflow: Postgres + Heroku SSL SYSCALL 错误

还有一张关于自动重新连接的 Rails 票: https ://github.com/rails/rails/issues/9421

这看起来是一个很好的线索,但似乎没有人解决这个问题。Heroku 的 Postgres 似乎有些不稳定,Rails<4 并不能很好地恢复。

  • 01:17:26 到 01:17:27: 58 个 GET 请求被“服务”(我想这些是排队的请求?由于 30 秒超时,客户端早已消失。为什么这些请求仍然通过?)
  • 01:17:51:一切恢复正常。

有任何想法吗?我将打开 Heroku 支持票,但不确定我是否会以免费用户的身份获得任何地方。

4

1 回答 1

3

答案在这里:

T01:02:21.144033+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=HEAD path=/register host=www.puckpicks.ca fwd="50.18.57.7" dyno=web.1 connect=1ms service=30000ms status=503 bytes=0

您通常会看到这种模式,其中一个长时间运行的操作开始占用队列以获取所有进一步的请求。

Heroku 路由器将在 30 秒后丢弃一个长时间运行的请求,但它后面的 dyno 将继续处理该请求直到完成。但是,路由器并没有意识到这一点,因此它会将新请求发送到那个忙碌的测功机。这种影响趋于复杂,您会在 New Relic 中看到排队,最终出现 H12 错误,即使对于不相关的 URL(如静态资产)也是如此。

您可能想要安装类似 rack-timeout 的东西,这将确保在 dyno 级别也丢弃长时间运行的请求。具体来说, rack-timeout 在发生这种情况时会引发 TimeoutError。https://github.com/kch/rack-timeout

有了这些,复合效应不太可能发生,但仍需要解决长期行动。New Relic 是一个很好的工具,可以提供对应用程序的可见性以识别长期运行的操作。然后您可以优化它们并确保它们能够在合理的时间内完成,我建议将所有请求保持在 500 毫秒以下。如果他们正在执行任何固有的长任务,您应该尝试将这些任务卸载到后台工作人员。

如果您有更高流量的生产应用程序,我还建议您使用Unicorn (如果您还没有的话),这样您的应用程序就可以处理并发请求。这将为您提供更多的并发性,帮助减少排队时间,并为您提供每个测功机的整体性能。

于 2013-05-01T14:27:48.760 回答