【问题标题】:Heroku Slow Loading ThroughoutHeroku 整个过程加载缓慢
【发布时间】:2013-08-30 09:02:36
【问题描述】:

我的 Heroku Rails 加载总是非常缓慢,而且不仅是在第一次启动时。

它不会在生产模式下缓慢加载。

我安装了 New-Relic,我有两个 Dynos 正在运行,我有 PostgreSQL Crane Plan。但是当我启动我的应用程序时,它通常需要大约 30 秒才能加载,并且 60% 的时间会直接转到 Application Error,如果我检查我的日志,我会得到 Memory Quota Exceeded。即使我转到源代码中没有 Ruby 的静态页面,它仍然会加载缓慢。有时我设法连接到我的应用程序,并且在从一个页面导航到另一个页面时通常需要大约 10 秒才能加载。 我一直在网上寻找很久,我发现的所有最常见的答案就是添加一个额外的测功机,但这并没有帮助。

我也在 Unicorn 上运行

这些是来自 movies#show 页面的日志,该页面首先加载然后崩溃

Started GET "/movies/61708" for 81.34.154.155 at 2013-08-29 23:08:23 +0000
2013-08-29T23:08:30.093034+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path=/?page=7 host=www.websitename.com fwd="81.34.154.155" dyno=web.1 connect=1ms service=30000ms status=503 bytes=0
2013-08-29T23:08:31Z app[postgres.8916]: [BLUE] duration: 6945.946 ms  statement: SELECT "movies".* FROM "movies" 
2013-08-29T23:08:41+00:00 app[heroku-postgres]: source=HEROKU_POSTGRESQL_BLUE measure.current_transaction=2844 measure.db_size=60732536bytes measure.tables=23 measure.active-connections=10 measure.waiting-connections=0 measure.index-cache-hit-rate=1 measure.table-cache-hit-rate=1
2013-08-29T23:08:45.401673+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path=/movies/63724 host=www.websitename.com fwd="81.34.154.155" dyno=web.1 connect=2ms service=30001ms status=503 bytes=0
2013-08-29T23:08:45.445116+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path=/movies/63704 host=www.websitename.com fwd="81.34.154.155" dyno=web.2 connect=3ms service=30000ms status=503 bytes=0
2013-08-29T23:08:52.684401+00:00 heroku[web.2]: Process running mem=512M(100.0%)
2013-08-29T23:08:52.684613+00:00 heroku[web.2]: Error R14 (Memory quota exceeded)
2013-08-29T23:08:53.647059+00:00 app[web.1]: E, [2013-08-29T23:08:53.384868 #2] ERROR -- : worker=0 PID:5 timeout (61s > 60s), killing
2013-08-29T23:08:54.375154+00:00 app[web.1]: E, [2013-08-29T23:08:54.374971 #2] ERROR -- : reaped #<Process::Status: pid 5 SIGKILL (signal 9)> worker=0

有人知道解决办法吗?

【问题讨论】:

  • 再次检查您的日志;在此处粘贴相关位。在您的日志中寻找模式,建议循环/悬挂在不应该存在的地方。也许您一次从数据库中加载了太多。您正在消耗大量内存。解决方案是确定消耗的来源并修复它。我不是在刻薄 - 仅根据您提供的描述,我们无法为您提供帮助。
  • 我已经添加了日志。但问题是,我什至还没有启动,所以只是我从数据库中请求信息。我的数据库甚至无法处理一个用户?
  • 你有多少部电影?一个简单的选择需要 7 秒是相当荒谬的。您真的没有任何理由将整个表作为 Rails 模型转储到内存中 - 这很可能是您遇到问题的根源。
  • 什么意思?电影表中目前有 60k 行,这应该不是问题吗?我正在为 PostgreSQL 起重机付费,它应该能给我 1000 万行
  • 实际上,PostgreSQL Crane 应该给我无限的行和 410 MB 的随机存取内存

标签: ruby-on-rails ruby postgresql heroku


【解决方案1】:

您在 cmets 中提到您的 movies 表中有 60,000 行。从您的日志看来,您正在执行以下操作:

Movie.all

这将生成一个类似于我们在您的日志中看到的 SQL 查询。

SELECT "movies".* FROM "movies"

Postgres 的内存/存储容量与您的问题无关。您的数据库可能位于具有 96G RAM 的专用服务器上。在 Heroku 端你仍然会遇到同样的问题。

当您执行Movie.all 之类的操作时,您正在为所有60,000 记录创建Movie 的内存中ruby 类实例。这需要时间和空间。

您可能还一次将太多(我敢说所有?!)这些记录呈现到单个网页。这只是方式在单个请求期间呈现太多数据,无论您是否在 Heroku 上。

Heroku 对其请求的运行时间有 30 秒的硬性限制。你达到了这个极限。尝试小得多的数据子集,即使只是作为测试,看看它是否能解决您的问题。我打赌它会的。

Movie.limit(10)

【讨论】:

  • 拜托,你真的认为我会在一页上渲染 60,000 部电影吗?我使用分页并将其限制为 20
  • 也许你这样做了,但你仍然在 somewhere 调用Movie.all,导致所有 60k 记录加载到内存中。你的日志不会说谎。
  • 我的控制器@explore_movies = Movie.limit(20).where('release_date is not null').all(:order =&gt; "release_date desc")
  • 那么我该如何摆脱all,同时仍然有.where 和:order。我仍然限制在 20
  • Movie.where('release_date is not null').order("release_date desc").limit(20)
猜你喜欢
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 2018-07-06
  • 2018-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多