4.2.x 系で調査。5.x系でかわっているかもしれない(おえてない)
こんな構成
ActiveRecord::Core <>--- ConnectionHandler <>--- ConnectonPool
|
| include
v
ActiveRecord::Base
ConnectionHandler
コネクション全般を管理する
ActiveRecord::Core
(Module)で定義されてる connection_handler
メソッドを使うと取得可能
ConnectionHandlerの取得
ActiveRecord::Base.connection_handler
おもな役割はコネクションプールの管理
- アプリケーションがもつコネクションプール全体の管理 (
active_connections?
,clear_all_connections!
,connection_pool_list
) - 個々のコネクションプールの作成 (
establish_connection
) - 個々のコネクションプールの切断 (
remove_connection
)
個々のコネクションプールは オーナー をもち、通常は establish_connection
を呼んだクラスのselfである。
デフォルトのオーナーは ActiveRecord::Base
ConnectionPool
個々のコネクションプールは オーナー をもつ
ActiveRecord::BaseのコネクションPoolは、database.ymlにある、
Rails.envで定義された設定を使い接続する。
モデルごとにコネクションプールを作成する
レシーバーがオーナーのコネクションプールを作成する
オーナーがかわることに注意
establish_connection
class Hoge < ActiveRecord::Base
establish_connection adapter: 'mysql2', host:'localhost', username: 'hgoe', password: 'hogehoge'
end
100クラスで establish_connection
を呼ぶと、合計で101個のコネクションプールが作成される。
さらに接続数は101個のコネクションプールのプール数の合計値が上限である。
デフォルト値は 5 なので、最大接続数が505となる可能性がある。
さらに、unicornなどのアプリケーションサーバを使うと、Worker(プロセスxスレッド数)だけ接続される。
接続数を抑制する
通常は、デフォルトの接続以外にコネクションをわけたい場合は、抽象クラスを用意する
class SlaveConnectionModel < ActiveRecord::Base
self.abstract_class = true
establish_connection adapter: 'mysql2', host:'localhost', username: 'hgoe', password: 'hogehoge'
end
class Hoge < SlaveConnectionModel; end
class Foo < SlaveConnectionModel; end
参考