首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >rufus-scheduler中ActiveRecord对象的连接池问题

rufus-scheduler中ActiveRecord对象的连接池问题
EN

Stack Overflow用户
提问于 2012-06-29 00:17:35
回答 3查看 6.9K关注 0票数 15

我正在使用rufus-scheduler来运行一些频繁的作业,这些作业使用ActiveRecord对象完成一些不同的任务。如果有任何类型的网络或postgresql问题,即使在恢复之后,所有线程都将抛出以下错误,直到进程重新启动:

ActiveRecord::ConnectionTimeoutError (未能在5秒内获得数据库连接(等待了5.000122687秒)。最大池大小当前为5;请考虑增加它。

通过重新启动postgres可以很容易地重现该错误。我试过玩池子大小的游戏(最多15个),但没有成功。

这让我相信连接只是处于一种陈旧的状态,我以为调用clear_stale_cached_connections!就可以解决这个问题。

有没有更可靠的模式来做到这一点?

传递的块是一个简单的select和update活动记录调用,并且恰好与AR对象是什么有关。

rufus的工作:

代码语言:javascript
复制
scheduler.every '5s' do
  db do
    DataFeed.update  #standard AR select/update
  end
end

包装器:

代码语言:javascript
复制
  def db(&block)
    begin
      ActiveRecord::Base.connection_pool.clear_stale_cached_connections!
      #ActiveRecord::Base.establish_connection    # this didn't help either way
      yield block
    rescue Exception => e
      raise e
    ensure
      ActiveRecord::Base.connection.close if ActiveRecord::Base.connection
      ActiveRecord::Base.clear_active_connections!
    end
  end
EN

回答 3

Stack Overflow用户

发布于 2013-10-15 20:00:33

Rufus调度程序为每个作业启动一个新线程。另一方面,ActiveRecord不能在线程之间共享连接,因此它需要将连接分配给特定的线程。

当你的线程还没有连接时,它会从池中获取一个连接。(如果池中的所有连接都在使用中,它将等待,直到从另一个线程返回一个连接。最终超时并抛出ConnectionTimeoutError)

在Rails应用程序中,当你使用完它时,你有责任将它返回到池中,这是自动完成的。但是如果你在管理你自己的线程(就像rufus那样),你必须自己去做。

幸运的是,有一个api可以做到这一点:如果您将代码放在with_connection块中,它将从池中获得一个连接,并在连接完成时将其释放。

代码语言:javascript
复制
ActiveRecord::Base.connection_pool.with_connection do
  #your code here
end

在您的案例中:

代码语言:javascript
复制
def db
  ActiveRecord::Base.connection_pool.with_connection do
    yield
  end
end

应该会成功的.

http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html#method-i-with_connection

票数 15
EN

Stack Overflow用户

发布于 2013-08-02 20:01:51

原因可能是你有许多线程正在使用所有的连接,如果DataFeed.update方法花费的时间超过5秒,那么你的块可能会重叠。

试一试

代码语言:javascript
复制
scheduler.every("5s",  :allow_overlapping => false) do
#...
end

另外,尝试释放连接,而不是关闭它。

代码语言:javascript
复制
 ActiveRecord::Base.connection_pool.release_connection
票数 1
EN

Stack Overflow用户

发布于 2013-05-28 05:06:38

我不太了解rufus-scheduler,但我有一些想法。

第一个问题可能是rufus-scheduler上的错误,它不能正确地检查数据库连接。如果是这种情况,唯一的解决方案就是像您已经做的那样手动清除陈旧的连接,并将您的问题通知rufus-scheduler的作者。

另一个可能发生的问题是,您的DataFeed操作需要很长时间,并且因为它每5秒执行一次,所以Rails耗尽了数据库连接,但这是相当不可能的。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11248808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档