ActiveRecord::ConnectionTimeoutError 间歇性发生

23
无论何时我使用ActiveRecord的应用程序,都会在一段未知的时间后出现ConnectionTimeoutError。
ActiveRecord::ConnectionTimeoutError (could not obtain a database connection within 5 seconds.  The max pool size is currently 30; consider increasing it.):

之前它被设置为5,我们已经将其增加了,现在没有办法同时使用30个连接。我们只使用ActiveRecord来存储会话。

我们的database.yml文件如下:

development:
  adapter: sqlite3
  database: db/development.sqlite3
  pool: 30
  timeout: 5000

测试和生产环境的设置是相同的。


我一直在搜索这个问题,并刚刚发现了这篇文章:

https://groups.google.com/forum/#!msg/copenhagen-ruby-user-group/GEHgi_WudmM/gnCiwWqmVfMJ

其中提到 ActiveRecord 在完成连接后不会检查连接是否归还到池中?这是真的吗?我需要手动管理连接吗?

感谢任何建议!

编辑:我应该提到我正在运行Rails 3.1.3


你的 sqlite gem 是否良好且更新?sqlite 文件的权限是否正确? - quatermain
在终端中运行“rake middleware”并查找ActiveRecord :: ConnectionAdapters :: ConnectionManagement。 - Kyle C
@KyleC - 请查看我在你的帖子下面的评论。@quatermain - 我们Gemfile中与sqlite和数据库相关的宝石是activerecord-jdbc-adapter使用版本1.2.2activerecord-jdbcsqlite3-adapter使用版本1.2.2jdbc-sqlite3使用版本3.7.2 - Krista
说实话,我在这个项目中加入时,Gemfile 已经创建了这些 Gems,我们可能不需要其中的全部三个吗? - Krista
4个回答

14

Rails中有一个叫做ActiveRecord::ConnectionAdapters::ConnectionManagement的中间件,它会在每次请求后清除活动连接,以免它们继续存在。检查你的中间件,确保你已经有了它(默认情况下是有的),运行"rake middleware"。你不需要手动管理连接来回答你的最后一个问题。

在你的控制台中运行这个命令。

   ActiveRecord::Base.clear_active_connections!

我假设你的意思是运行 "rake middleware" 命令,因为你上面的评论是这么说的?以下是 "rake middleware" 命令的输出:_请注意_,其中包括 ActiveRecord::ConnectionAdapters::ConnectionManagement... use ActionDispatch::Reloader use ActionDispatch::Callbacks **use ActiveRecord::ConnectionAdapters::ConnectionManagement** use ActiveRecord::QueryCache use ActionDispatch::Cookies use ActiveRecord::SessionStore - Krista
1
在你的控制台中,尝试运行 ActiveRecord::Base.clear_active_connections!。 - Kyle C
我还必须在一切重新正常运行之前重新启动我的Apache / Passenger。 - bass-t
2
这只是一个答案,如果你现在想要清除连接 - 它不会阻止它再次发生。 - Guillaume Roderick
仅补充一下:我遇到了一个问题,Rails 4构建的一部分gem(rollbar)导致连接未正确关闭。在这种情况下,正确的修复方法是打补丁或删除该gem。 - Guillaume Roderick
显示剩余5条评论

2

我在我的Sinatra应用程序上使用了这段代码

after do
  ActiveRecord::Base.clear_active_connections!
end   

这解决了我的问题。


你把这个放在哪里?放在你的应用控制器里吗? - Catfish

2

适用于Rails 5,因为Puma是默认服务器。

如果您使用像Puma、Phushion Passenger这样的线程服务器,它们会创建多个相同应用程序的线程。这样可以通过并发执行每个传入请求来加速应用程序的运行。

确保池大小等于或大于线程数。我遇到了一个问题,即我的几个线程给我返回ActiveRecord :: ConnectionTimeoutError,问题很模糊,因为它不经常出现。


1
这对我有用。我一直在使用Puma运行我的Rails应用程序,并使用默认池计数(即5)。 - elquimista

2
我也遇到了一个类似的问题,是在使用Sinatra应用时出现的。我添加了相应的代码:

after do
  ActiveRecord::Base.clear_active_connections!
end 

我向我的应用程序控制器寻求帮助,它解决了我的问题。

这个结构被称为“过滤器”,它在每个请求之后进行评估。

我不确定应用程序实际上发生了什么,但我会怀疑每个请求后连接没有被关闭。


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