Database connection pooling

。_饼干妹妹 提交于 2019-12-10 16:38:59

问题


I created a small chat application in Sinatra and jQuery on heroku. It simply inserts a message to a database when user submits it. And also downloads new messages every 2 seconds. After a few minutes of testing it stopped working and I received an email form heroku:

Hi,

We noticed that the gisekchat app had a large number of connections open to the shared database. We had to limit the number of connections to the shared database due to performance reasons. Can you either reduce the number of overall connections to the shared db or move to a dedicated database?

It does appear that you're not taking advantage of connection pooling and are opening a new connection to the database for each request from your app.

Thanks, -Chris

This is the action supporting submitting a message (receiving is very similar):

post '/send' do
  con = con = PGconn.connect($dbhost, 5432, "","",$dbname, $dbuser, $dbpass)
  con.exec("insert into messages(usr, msg, date) values('#{params[:usr]}','#{params[:msg]}', now())")    
end

How should I change it to enable connection pooling?


回答1:


Yeah well it's true, you really are opening a new connection to the database each time there is a 'send'-post send.

So you'll need to change that. One Possibility may be, to open the connection globally:

 $con = PGconn.connect($dbhost, 5432, "","",$dbname, $dbuser, $dbpass)

This should be done after you initialized your $dbname... variables, but before you use any routes.

However, if you are using the modular sinatra version, instead of the classic one, you could declare an instance variable with

attr_accessor :con

and initialize it before the app is started.




回答2:


Robustus is halfway there creating an instance variable will create a connection for each instance of your class.

What you want is a thread-safe data store api that will use a mutex to handle access to your connection object(s). This is the control mechanism that ActiveRecord uses in rails.

I have created a ruby gem called 'q' that provides a simple mechanism for doing this. The gem is located here: https://github.com/jacobsimeon/q

install like this git clone https://github.com/jacobsimeon/q

then add this to whatever file initializes your app: require 'q/resourcepool'

then, create your datastore during initialization:

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

then, you can use @datasource to execute commands against your database

post '/send' do
  @datasource.exec(standard_postgres_params)
end

Contact me on github or twitter (@jacobsimeon on both) if you're interested in going this route.




回答3:


I've used the 'classic' sinatra application and I've obtained the same result by declaring class variables : e.g @@db_connection. This always uses the same connection and works for me.



来源:https://stackoverflow.com/questions/7971832/database-connection-pooling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!