当前位置 : 主页 > 编程语言 > ruby >

这是在Ruby中保持连接池的首选方法吗?

来源:互联网 收集:自由互联 发布时间:2021-06-23
我对 ruby(在日常编写 java)方面不是很有经验,我正在尝试找到保持连接池之类的“ Ruby方式”.我有多个线程的独立Ruby应用程序,我想出了类似下面的内容. 请注意Mongo的本机ruby驱动程序提
我对 ruby(在日常编写 java)方面不是很有经验,我正在尝试找到保持连接池之类的“ Ruby方式”.我有多个线程的独立Ruby应用程序,我想出了类似下面的内容.

请注意Mongo的本机ruby驱动程序提供的MongoClient在内部维护连接池,所以我需要的是能够保留一个MongoClient实例

require 'mongo'

module MongoPool

  # module instance var to ensures only one exists
  @mongo = nil

  def self.lazy_create
    @mongo ||= Mongo::MongoClient.new('localhost', 27017, :pool_size => 5, :timeout => 5)
  end

  # when getting connection lazily create pool by assigning to @mongo only if nil
  def connection
    MongoPool.lazy_create
  end

end

class PeopleRepository

  include MongoPool

  def random_person
    coll = connection['test']['people']
    coll.find_one
  end

end

# usage
PeopleRepository.new.find_one

我知道它有效(检查@mongo的object_id在几次调用中保持不变),但这是保持一切的首选方法吗?

可能有多个存储库,因此每个存储库都可以包含MongoPool并使用它的连接.上述解决方案有任何缺点吗?还有其他方法我应该注意吗?

注意:问题更多的是关于如何以Ruby方式执行操作,而不是关于如何一般地执行此操作(因为我使用它).

你真的不需要另一个宝石来实现这一点,实际上Mongoid的驱动程序(Moped)还不支持连接池.

与在rails中使用应用程序级别常量的建议类似,您只需在无头应用程序中使用类变量,以便MongoClient实例在应用程序基类的所有调用中都是相同的单个对象/池实例.

例如,你可以这样做:

require 'mongo'

class MyApplication
  include Mongo

  # creates a single class instance, sets pool size but won't connect until used (lazy)
  @@client = MongoClient.new('localhost', 27017, :pool_size => 5, :connect => false)

  def do_something
    @@client['my_db']['my_collection].insert({ "foo" => "bar"})
  end
end

简单而且非常直截了当.您没有必要使用上面使用的模块方法.

你提到了Torquebox所以我假设你正在使用JRuby并让Torquebox为你管理你的应用程序的线程池.

确保你运行的是mongo ruby​​驱动程序的1.8.3或更高版本,其中包括一些主要的修复和改进,以便在这种类型的线程设置下运行.我们解决了一些线程安全问题,并大大提高了连接池的并发性.

希望有所帮助.

网友评论