我正在尝试了解生产中的问题,所以我将这个代码段放在dev中的控制器操作中进行测试:
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
。我可能会将此问题作为另一个问题提交。
答案 0 :(得分:0)
一些评论:
mysql2
宝石。 mysql
gem在等待数据库响应时保留GIL。