Ruby 数据库连接池

Ruby 数据库连接池,ruby,database,sinatra,Ruby,Database,Sinatra,我用Sinatra和heroku上的jQuery创建了一个小型聊天应用程序。它只是在用户提交消息时将其插入数据库。并且每2秒下载一次新消息。经过几分钟的测试,它停止了工作,我收到了一封来自heroku的电子邮件: 嗨 我们注意到gisekchat应用程序有大量的连接 打开共享数据库。我们必须限制连接的数量 由于性能原因,无法访问共享数据库。你也可以吗 减少到共享数据库的总连接数或移动到 专用数据库 您似乎没有利用连接池 并且正在为来自的每个请求打开到数据库的新连接 你的应用程序 谢谢, -克里斯

我用Sinatra和heroku上的jQuery创建了一个小型聊天应用程序。它只是在用户提交消息时将其插入数据库。并且每2秒下载一次新消息。经过几分钟的测试,它停止了工作,我收到了一封来自heroku的电子邮件:

我们注意到gisekchat应用程序有大量的连接 打开共享数据库。我们必须限制连接的数量 由于性能原因,无法访问共享数据库。你也可以吗 减少到共享数据库的总连接数或移动到 专用数据库

您似乎没有利用连接池 并且正在为来自的每个请求打开到数据库的新连接 你的应用程序

谢谢, -克里斯

这是支持提交消息的操作(接收非常类似):


我应该如何更改它以启用连接池?

是的,这是真的,每次有“发送”后发送时,您都会打开到数据库的新连接

所以你需要改变这一点。一种可能是全局打开连接:

 $con = PGconn.connect($dbhost, 5432, "","",$dbname, $dbuser, $dbpass)
这应该在初始化$dbname后完成。。。变量,但在使用任何路由之前

但是,如果您使用的是模块化sinatra版本,而不是经典版本,则可以使用

attr_accessor :con
并在应用程序启动之前对其进行初始化。

罗布斯已经成功了一半 创建实例变量将为类的每个实例创建连接

您需要的是一个线程安全的数据存储api,它将使用互斥来处理对连接对象的访问。这是ActiveRecord在rails中使用的控制机制

我已经创建了一个名为“q”的RubyGem,它提供了一个简单的机制。 创业板位于:

像这样安装
git克隆https://github.com/jacobsimeon/q

然后将其添加到初始化应用程序的任何文件中:
需要“q/resourcepool”

然后,在初始化期间创建数据存储:

class DataConnection < ResourcePool
  def create_resource
    PGConn.connect(@config)
  end
end
@datasource = ResourcePool.new(your_connection_info_here)

如果您对这条路线感兴趣,请通过github或twitter(@jacobsimeon)与我联系。

我使用了“经典”sinatra应用程序,并且通过声明类变量获得了相同的结果:例如@db\u connection。这总是使用相同的连接并对我有效。

是的,这似乎是对的,如果线程安全是您需要实现的,但这通常只能在模块化版本中实现,而不能在经典版本(afaik)中实现。从示例代码的外观来看,这看起来像是我们在处理sinatra应用程序。我不确定,但我认为每个请求都是通过heroku免费主机上的一个新线程发出的。“模块化版本”是什么意思?编写sinatra应用程序有两种不同的版本。经典的一个,其中“main”文件包含路由和操作,例如没有实例变量;模块化的一个,您实现了一个从Sinatra::base继承的类实例变量仍然可用,不是吗?如果您不是子类化Sinatra::Basejacob,那么范围会更广,实际上我现在已经测试过了,如果您在经典环境中声明一个来自
get的实例变量。。。结束
块您将无法在
获取中使用它。。。结束
块。
class DataConnection < ResourcePool
  def create_resource
    PGConn.connect(@config)
  end
end
@datasource = ResourcePool.new(your_connection_info_here)
post '/send' do
  @datasource.exec(standard_postgres_params)
end