Heroku:在简单的Rails应用程序上定期停机15分钟

时间:2013-05-01 13:29:59

标签: ruby-on-rails postgresql heroku timeout

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

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

我每隔几个小时就会完全停止15分钟。

enter image description here

由于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 ::错误(SSL SYSCALL错误:检测到EOF)(除此之外:我注意到Heroku的日志声明乱序,很奇怪。)

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

更多StackOverflow: Postgres + Heroku SSL SYSCALL error

关于自动重新连接的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支持票,但不确定我是否可以作为免费用户使用。

1 个答案:

答案 0 :(得分: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将继续处理请求直到完成。但路由器并不知道它,所以它会向忙碌的dyno发送新的请求。这种效果往往会复合,你会看到New Relic排队,最终H12错误甚至是无关的URL,比如静态资产。

您可能希望安装像rack-timeout这样的东西,这样可以确保在dyno级别也可以删除长时间运行的请求。具体来说,当发生这种情况时,机架超时会引发TimeoutError。 https://github.com/kch/rack-timeout

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

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