在Heroku上,Rails应用程序运行非常缓慢

3
一个Rails应用程序具备以下特点:
一些模型从外部MySQL数据库中访问数据。以下代码被用于将外部数据库设置给该模型:
class Foo < ActiveRecord::Base

  establish_connection ENV['EXTERNAL_DATABASE_URL']
  self.table_name = 'foos'

  ...

end

在我的笔记本上本地运行应用程序时,我得到了以下请求执行时间:
Completed 200 OK in 374ms (Views: 118.1ms | ActiveRecord: 198.6ms)

当我将它上传到Heroku并在应用程序中使用时,同一请求的执行时间如下:
Completed 200 OK in 8000ms (Views: 901.6ms | ActiveRecord: 6609.2ms)

当我在Heroku上运行时,无论是ActiveRecord还是Views的时间都非常长。

  • 可能是外部数据库的问题吗?
  • 我如何检查这个问题?
  • 如果不是,可能是什么问题?

编辑

NewRelic报告

NewRelic显示瓶颈在于数据库。然而,显然不是数据库在查询上花费的时间,因为当我本地运行时,它并不需要那么长时间。所以我必须认为这是延迟引起的问题?


外部数据库可能会是一个问题。数据库托管在哪里?Heroku和数据库之间的延迟有多大?每个请求中您对数据库执行多少个请求? - spickermann
数据库托管在亚马逊RDS上,但位于圣保罗地区,而不是美国。在此示例中有18个请求。我不确定如何测量Heroku和数据库之间的延迟。我该怎么做?谢谢! - João Daniel
本地数据库查询可能需要3-5毫秒。我敢打赌美国和圣保罗之间的延迟至少为100毫秒。这意味着每个请求至少需要多200毫秒。我并不感到惊讶。将数据库移动到亚马逊数据中心amazon-web-services::us-east-1,那里是Heroku托管的地方。 - spickermann
由于所有请求到数据库的延迟累加并且总体上减缓了每个页面视图,因此将数据库尽可能靠近您的Web服务器非常重要。这意味着至少在同一数据中心,对于速度狂热者,如果可能的话在同一台服务器上。 - spickermann
您可以在Newrelic的监控/数据库下检查数据库响应时间。我有一个运行在Heroku上使用他们的PostgreSQL服务的应用程序。该应用程序的平均数据库响应时间为2.5毫秒。你的呢?250毫秒。 - spickermann
显示剩余4条评论
1个回答

2
数据库请求所需的时间取决于以下几个因素:
  1. 数据库管理系统查找数据需要多长时间?这取决于查询的复杂性、索引的存在以及表的大小。
  2. Rails从结果中构建ActiveRecord对象需要多长时间?这取决于每个页面上的结果数量。
  3. 将请求从Web服务器发送到数据库服务器以及将结果从数据库服务器发送回Web服务器需要多长时间?这种延迟取决于服务器之间的距离。
当您的Web服务器由Heroku在美国(us-east-1)托管,但您的数据库位于圣保罗的Amazon RDS上时,每个对数据库的请求都会为网页的整体响应时间增加150毫秒的延迟。如果在一个Web请求中执行更多的数据库请求,则此问题会变得更加严重。
我建议尽可能将数据库移至靠近Web服务器的位置。如果可能,在美国同一数据中心内(在同一台服务器上是最快的)。或者考虑在圣保罗自己托管Web服务器(也许使用Amazon OpsWorks)。

我将数据库迁移到了Heroku的同一地区,现在请求时间实际上比本地运行还要短。非常感谢!! - João Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接