Rails 4:heroku基本计划上的ConnectionTimeoutError

我们正在开发一个简单的Rails 4 webapp ,由Heroku托管,提供免费计划。

最近,我们遇到了一些ActiveRecord::ConnectionTimeoutError – 每隔几天一次 – 我们并不真正理解它背后的原因。

你可能想看看这里的完整堆栈。

我们知道Heroku设置了与Postgres数据库的20个连接的池限制,这很可能是抛出exception的原因。 这是我们的猜测:

我们使用Herku调度程序每小时启动一次rake任务,并且由于该任务查询数据库,问题可能在于这些连接在使用后没有从池中释放。 所以我们试图将所有内容放在一个块中:

 ActiveRecord::Base.connection_pool.with_connection do #code with queries end 

但这似乎并没有解决问题。 你有更好的建议/解释吗?

我们非常感谢任何帮助和/或见解,以及我们应该如何调试此问题。


PS:我们还尝试在专用的初始化程序中添加以下代码,但它没有解决问题

 Rails.application.config.after_initialize do ActiveRecord::Base.connection_pool.disconnect! ActiveSupport.on_load(:active_record) do config = ActiveRecord::Base.configurations[Rails.env] || Rails.application.config.database_configuration[Rails.env] config['reaping_frequency'] = ENV['DB_REAP_FREQ'] || 10 # seconds config['pool'] = ENV['DB_POOL'] || 20 ActiveRecord::Base.establish_connection(config) end end 

根据我的经验,这些问题将出现在基本的Heroku计划中。 有许多方法可以在不增加成本的情况下降低频率。 但是你永远不会在基本/爱好堆栈中出现0%。

这就是为什么在我的经验中…直到你点击’premium-yanari’你才能获得高可用性。 您可以获得99.95%的预期正常运行时间,而免费的99.5%。 听起来不是很多,但Heroku因为某种原因收取150美元的额外费用(与’标准yanari’计划相比)。

在连接池,收割频率和分叉的所有优化之后,如果您的进程无法访问数据库服务器,您将获得超时。 如果这是唯一的原因,它很少发生,这可能是你的情况。 只有在我升级到’premium-yanari’之后,这个看似随机的超时才会停止。

我不建议你开始支付200美元/月作为解决方案。 您可以通过下面的一些建议接近零。 调整并发性,数据库连接以及试验各种选项(如超时)需要一些跟踪和错误 – 因为似乎没有插件和突突公式为您提供所有这些参数的完美组合。

1)转移到Unicorn以更好地控制您的进程和数据库连接。 这是一个示例unicorn.rb文件https://gist.github.com/blotto/8005531b9c94f3732240

2)增加你的超时(目前为5秒)。 请参阅unicorn.rb:

  timeout ENV['REQUEST_TIMEOUT'].to_i > 0 ? ENV['REQUEST_TIMEOUT'].to_i : 15 

3)确保你使用的是最新的稳定版Rails 4.1.1。 因为4.0.x确实有一些Postgres适配器问题。 请参阅https://github.com/rails/rails/issues/12867