【问题标题】:rails application running out of database connectionsrails 应用程序耗尽数据库连接
【发布时间】:2014-07-24 05:40:28
【问题描述】:

尽管我的 Rails 应用程序中有 50 个池,但我还编写了一个脚本,使用流行的守护程序 gem 定期处理任务。这是它的样子:

class Responder
  def initialize
    @queue = Queue.new
  end
  # add to queue
  def produce(msg)
    @queue << msg
  end

  # take from queue
  def consume
    Thread.new do

      loop do
        sleep(1)
        if !@queue.empty?
          data = @queue.pop
          process(data)
        end
      end

    end 
  end
end

class EmailResponder < Responder
  def process(message)
    Alert.where(id: message[:id]).send_mail 
  end
end

class GeocodeResponder < Responder
  def process(message)
    Report.where(id: message[:id]).geocode_data
  end
end

class RedisListener
  def initialize(host,port)
    @host = host
    @port = port
    @email_sms = EmailResponder.new
    @geocode = GeocodeResponder.new
    # timeout so we wait for messages forever
    @redis = Redis.new(:host => @host, :port => @port, :timeout => 0)
  end

  def start_producers
    thread = Thread.new do
      @redis.subscribe('juggernaut') do |on|
        on.message do |event, msg|
          @email_sms.produce(msg)
          @geocode.produce(msg)
        end
      end
    end
  end

  def start_consumers
      @email_sms.consume
      @sidekiq.consume
  end
end

  listener = RedisListener.new('127.0.0.1', 6379)
  listener.start_producers
  listener.start_consumers

问题是很多项目都是通过 redis 来的,所以队列建立起来了,我最终使用了越来越多的数据库连接,以至于它在达到 postgresql 最大连接数时崩溃。我不想限制队列的大小,否则我可能会丢失来自 redis 的数据。我宁愿让队列不断增长,实际上只是限制数据库连接。如何在这个 Rails 守护进程中限制数据库连接(所以当我使用 ActiveRecord 对象,如 Alert.where(...) 或 Report.where(...) 时,它只会阻塞,直到数据库连接空闲)?

我尝试将此添加到脚本中:

ActiveRecord::Base.configurations['production']['pool'] = 10

但是好像没有效果。

【问题讨论】:

    标签: ruby-on-rails ruby postgresql


    【解决方案1】:

    我认为它与这个话题有关。 Connection pool issue with ActiveRecord objects in rufus-scheduler 总之,活动记录不能在线程之间共享连接池

    def handle_db_pools(&block)
      ActiveRecord::Base.connection_pool.with_connection &block
    end
    
    handle_db_pools do
      Alert.where(id: message[:id]).send_mail 
    end
    

    希望这会为您指明正确的方向

    【讨论】:

    • 奇怪的是我删除了为发送电子邮件而创建的线程池,这个问题就消失了。仍在试图找出原因。
    猜你喜欢
    • 2010-09-30
    • 2017-03-25
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-10
    • 2019-04-07
    • 2014-06-20
    相关资源
    最近更新 更多