Rubyで一度接続したコネクションを使いまわす方法(コネクションプール)
RubyでDBなどにアクセスしたり、他のサーバへコネクションを接続したりすると思いますが、頻繁に接続がある場合はその度に接続をしていてはコストになります。
対応として、コネクションを一定時間維持して、そのコネクションを使いまわすとよいです。
方法
1. まずはコネクション接続のクラスをsingletonとして作成
require 'socket' require 'singleton' class ConPool include Singleton # コネクションプールの作成 def initialize @pool = {} end # コネクションの作成 def create_connection(host, port) TCPSocket.new(host, port) end # コネクションの取得 def get_connection(host) if @pool.key?(host) && @pool[host].length > 0 # 既にコネクションプールにコネクションが保存されている場合は取得 con = @pool[host].shift else # 保存されていない場合はコネクションを新規に作成 con = create_connection(nid) unless con end con end # コネクションの返却(コネクションプールへ) def return_connection(host, con) if @pool.key?(host) @pool[host] << con else @pool[host] = [con] end end # コネクションの削除 def delete_connection(host) @pool.delete(host) end end # class ConPool
2. 実際にコネクションを利用するアプリケーション等で上記のコネクションプールクラスを呼び出す
# コネクション取得 con = ConPool.instance.get_connection(host) #{処理} # コネクション返却 ConPool.instance.return_connection(host, con)
コネクションの数や保存期間に制限をつけたい場合
1. コネクションプールクラスにインスタンス変数として
maxlength(コネクション最大数)
expire_time(保持期間)
を設定する
2. コネクションの取得時と返却時に上記を確認して、保存すべきか破棄するかを判断する
・ ・ ・ attr_accessor :maxlength attr_accessor :expire_time def initialize(maxlength = 10, expire_time = 60) @pool = {} @maxlength = maxlength @expire_time = expire_time end ・ ・ ・ # コネクションの取得 def get_connection(host) con,last = @pool[host].shift if @pool.key?(host) && @pool[host].length > 0 if con && last < Time.now - @expire_time con.close # 保存期間を過ぎている古いコネクションの場合は破棄する con = nil end con = create_connection(host) unless con con end # コネクションの返却(コネクションプールへ) def return_connection(host, con) if @pool.key?(host) && @pool[host].length > 0 if @pool[host].length > @maxlength con.close # コネクションプールが満杯の場合は保存せずにコネクションを破棄する else @pool[host] << [con, Time.now] # コネクションを保存する際に時間も一緒に保存する end else @pool[host] = [[con, Time.now]] end end ・ ・ ・