我正在使用第二个数据库,其中包含我的API中的数据集。
每个API请求可以有多达3个查询的数据库,所以我把他们分为三个线程。为了保持线程安全,我使用了一个连接池。
但是在整个代码运行之后,ConnectionPool线程并没有终止,所以基本上每次发出请求时,服务器上都会有一个新的线程,直到基本上没有内存剩余。
有没有办法关闭连接池线程?或者我在为每个请求创建连接池时做错了什么?
我这样设置连接池:
begin
full_db = YAML::load(ERB.new(File.read(Rails.root.join("config","full_datasets_database.yml"))).result)
resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(full_db)
spec = resolver.spec(Rails.env.to_sym)
pool = ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec)
然后,我运行queries数组并将结果获取到查询中
returned_responses = []
queries_array.each do |query|
threads << Thread.new do
pool.with_connection do |conn|
returned_responses << conn.execute(query).to_a
end
end
end
threads.map(&:join)
returned_responses
最后,关闭连接池中的连接:
ensure
pool.disconnect!
end
2条答案
按热度按时间gopyfrb31#
遵循Rails中处理多个数据库的官方方法:
https://guides.rubyonrails.org/active_record_multiple_databases.html
我不能给予你一个准确的答案,因为我没有你的源代码,以充分了解整个上下文。如果我发送以上设置不适用于您的用例,您可能会错过一些后台清理任务。您可以参考以下文档:
https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html
pu82cl6c2#
由于您希望直接进行SQL查询,而不利用ActiveRecord作为ORM,但您确实希望利用ActiveRecord连接池,因此我建议您创建一个新的抽象类,如
ApplicationRecord
:您需要在
database.yml
中配置数据库full_datasets_database
,以便connects_to
能够连接到它。然后,您将能够直接连接到该数据库,并通过引用该类而不是
ActiveRecord::Base
对它进行直接SQL查询:连接池将透明地与不同的池一起发生:
您可能需要进行额外的配置,比如将模式转储到
db/full_datasets_schema.rb
,但是您需要进行的任何额外的故障排除或配置都将在https://guides.rubyonrails.org/active_record_multiple_databases.html中进行描述。简短的解释是,您应该尽可能多地利用ActiveRecord,以便您的实现干净而直接,同时仍然允许您直接使用原始SQL。