1
我尝试了解在生产中的问题,所以我扔在开发的控制器操作中这个片段进行测试:为什么不能同时运行这些线程化的ActiveRecord查询?
start = Time.now
num_threads = 6
results = Queue.new
saved_results = []
threads = []
connections = []
semaphore = Mutex.new
# start threads
(1..num_threads).each do |i|
threads << Thread.new do
#semaphore.synchronize { connections << ActiveRecord::Base.connection } # for cleanup?
#ActiveRecord::Base.connection.execute("select sleep(1.6);") # runs sequentially
sleep(1.6) # runs concurrently
result = User.find_by_id(i)
results << [i, result]
end
end
# end option 1 - let everyone finish
threads.each(&:join)
# end option 2 - simulate early exit condition
#while saved_results.count < 3 do saved_results << results.pop end
#threads.each(&:exit)
# cleanup/close open connections?
#connections.select(&:active?).each(&:disconnect!)
elapsed = Time.now - start
render :text => [ elapsed.to_s, saved_results.size, results.size ].join(", ")
sleep(1.6)
执行大约1.6
秒,符合市场预期。
但是,ActiveRecord select sleep(1.6);
需要6 * 1.6 = 9.6
秒,尽管mysql控制台show processlist;
显示为每个线程*打开独立连接。
发生了什么事?为什么ActiveRecord查询不能同时运行?我也在生产控制台中体验过这一点。
我确实有config.threadsafe!
设置在config/environment.rb
。如果有关系,我使用Rails 2.3。
*这些连接必须手动关闭?生产总是有很多无所事事的开放式连接,导致Mysql::Error: Too many connections
。我可能会提出这个问题作为另一个问题。
刚刚用mysql2进行了测试,并且此示例正常工作。我最近遇到了另一个与半相关的问题:http://stackoverflow.com/questions/26001994和使用mysql2在那里没有帮助 – Kache