的ActiveRecord :: ConnectionTimeoutError
我收到此错误:
'could not obtain a database connection within 5 seconds (waited 5.001017 seconds). The max pool size is currently 16; consider increasing it.'
首先我得到了这个错误,我将计数从5提升到16.但它仍然在发生,我是唯一一个测试数据库的人。 当我是唯一的用户时,为什么会这样?
我不在铁轨上。 我在用:
ActiveRecord::Base.establish_connection ({ :adapter => 'mysql2', :database => 'ck', :host => 'localhost', :username => 'root', :password => '', :pool => 16, })
并使用Sinatra。
谢谢
正如Frederick指出的那样,您需要将打开的ActiveRecord连接返回到连接池。
如果您在线程模式下使用Thin服务器,则需要将其添加到Sinatra应用程序:
after do ActiveRecord::Base.connection.close end
…而不是使用ConnectionManagement建议。 原因是Thin将请求处理分为两个线程,而关闭ActiveRecord连接的线程与打开它的线程不同。 由于ActiveRecord按线程ID跟踪连接,因此会混淆并且不会正确返回连接。
听起来您在请求结束时没有返回到池的连接。 如果没有,则每个使用db的请求将消耗1个连接,最终您将耗尽池并开始获取您描述的错误消息
Active Record提供了一个机架中间件来处理这个ActiveRecord::ConnectionAdapters::ConnectionManagement
,它应该处理中间件链中早期的事情,而不是任何访问活动记录的东西。
您也可以自己处理连接管理。 文档有更多细节,但一种方法是将所有数据库访问都放在这样的块中
ActiveRecord::Base.connection_pool.with_connection do ... end
在块开始时检查连接并在之后检查它。
最好使用ActiveRecord提供的中间件 :
use ActiveRecord::ConnectionAdapters::ConnectionManagement
正如Frederick指出的那样,您需要将打开的ActiveRecord连接返回到连接池。
正如kuwerty建议的那样,当您使用Thin时, ConnectionManagement
将不会返回到池的连接。 我建议不要像kuwerty那样关闭当前连接,而是像这样返回到池的连接。
after do ActiveRecord::Base.clear_active_connections! end
对于那些想要重现问题的人,请尝试这个例子 。
编辑:
我解释了为什么使用中间件ActiveRecord::Connectionadapters::ConnectionManagement
不能在线程模式下使用Thin,你可以在这里找到。