生活随笔
收集整理的這篇文章主要介紹了
establish connection
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
慎用establish connection
在一個Rails應用中連接多個數(shù)據(jù)庫,我們常常這么做:
?
Ruby代碼??
class?Cookie?<?ActiveRecord::Base??????establish_connection?:monitor_spider??????...??end?? ?
這樣,在使用Cookie.find等操作的時候,就會連接到database.yml中monitor_spider配置的數(shù)據(jù)庫上操作。
以前一直都這么用,沒發(fā)現(xiàn)什么不妥。最近一個項目,由于啟動的進程比較多,老是碰到數(shù)據(jù)庫連接池鏈接獲取超時的錯誤。通過MySQL Client用命令:show processlist;
?
發(fā) 現(xiàn)數(shù)據(jù)庫連接數(shù)量一直居高不下,輕輕松松就上2k+的連接。通過讀Rails框架的connection_pool.rb文件代碼,發(fā)現(xiàn)在各模型中用 establish_connection連接數(shù)據(jù)庫會造成很大的問題。文件中類ConnectionHandler的 establish_connection方法代碼如下:
?
Ruby代碼??
def?establish_connection(name,?spec)??????????@connection_pools[name]?=?ConnectionAdapters::ConnectionPool.new(spec)??end?? ?對 應上面Cookie模型的配置,這里name的值會是Cookie。也就是說,有10個模型中使用了establish_connection配 置,@connection_pools中就會初始化10個ConnectionPool,如果每個ConnectionPool的pool size是20,那么應用運行的時候,將需要200(10 × 20)個數(shù)據(jù)庫連接。而我的應用中有兩類模型(連接到兩個數(shù)據(jù)庫),模型總數(shù)40+。按establish_connection的方式設置數(shù)據(jù)庫連接, 那么mysql的連接輕易就被消耗完了。
?
那要怎么處理呢?
?
我現(xiàn)在的思路是自己來維護數(shù)據(jù)庫連接池。
?
首先,對ConnectionAdapters進行一下改造,將如下代碼放到initializers中:
?
Ruby代碼??
module?ActiveRecord??????module?ConnectionAdapters???????class?ConnectionHandler????????def?specified_establish_connection(name,?spec)??????????@connection_pools[name]?=?ConnectionAdapters::ConnectionPool.new(spec)????????end?????????????????def?retrieve_connection_pool(klass)??????????if?klass.respond_to?(:pool_name)????????????pool?=?@connection_pools[klass.pool_name]????????????#?ActiveRecord::Base.logger.info?"pool:?#{pool.inspect}"????????????return?pool?if?pool???????????end??????????pool?=?@connection_pools[klass.name]??????????#?puts?pool.inspect??????????return?pool?if?pool??????????return?nil?if?ActiveRecord::Base?==?klass??????????retrieve_connection_pool?klass.superclass????????end??????end????end??end?? ?
在environment.rb中事先連接建立數(shù)據(jù)庫連接池:
?
Ruby代碼??
#specified?pool??config?=??YAML::load(File.open("config/database.yml"))??%w(monitor_center?monitor_spider).each?do?|pool_name|????spec?=?config[pool_name]????adapter_method?=?"#{spec["adapter"]}_connection"????ActiveRecord::Base.connection_handler.specified_establish_connection(pool_name,?ActiveRecord::Base::ConnectionSpecification.new(spec,?adapter_method))???end?? ?在模型中,定義方法pool_name:
?
Ruby代碼??
class?TaskStat?<?ActiveRecord::Base????def?self.pool_name;"monitor_spider";end????...??end???????class?TaskInfo?<?ActiveRecord::Base????def?self.pool_name;"monitor_center";end????...??end?? ?
?
這樣,TaskStat就會用monitor_spider pool,TaskInfo會用monitor_center pool。同時整個應用就只有三個ConnectionPool(外加默認的ActiveRecord::Base的)
通過這樣的改造之后,效果明顯,現(xiàn)在show processlist一般只有200~300的連接數(shù)。
轉(zhuǎn)載于:https://www.cnblogs.com/qinyan20/p/3643130.html
總結(jié)
以上是生活随笔為你收集整理的establish connection的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。