【问题标题】:Rails holding on to DB connections too long, can't run Stored ProceduresRails 保持数据库连接的时间过长,无法运行存储过程
【发布时间】:2016-05-10 12:51:32
【问题描述】:

我在使用 Rails 和我的 MySQL RDS 实例时遇到问题。我通过我们的 database.yml 文件将我的 rails 应用程序连接到它,该文件具有 10 个(现在 5 个)连接池。前几天,数据库的另一个用户尝试运行存储过程,但它不会执行。它被卡住了,只是在等待执行。用户查看了进程并注意到我们的 rails 用户有大约 30 个空闲进程,因此他们杀死了其中的一些。存储过程随即启动并毫无问题地运行。

我们在一个 r3.xlarge 实例上,在出现问题时总共有大约 100 个进程。这对我来说似乎并不高,我不确定为什么如果不释放一些进程就无法执行该过程。我想我的问题是,有没有办法告诉我的 Rails 应用程序在 x 秒后释放其中一些空闲连接,或者更好地控制这些连接?我可以编写一个 cron 来释放它们,但我很想用 rails/best 方式来做。

感谢您的帮助!

【问题讨论】:

    标签: mysql ruby-on-rails stored-procedures rds


    【解决方案1】:

    在我看来,您可能已达到 MySQL 实例的最大连接数限制。您可以在 MySQL 上运行 select @@max_connections 以找出限制。

    我不知道如何强制 Rails 关闭其分配的数据库连接。 每个服务器进程最多可以使用 池大小 个连接(即在您的情况下为 10 或 5 个)到数据库的线程。线程和进程之间的区别很重要:例如,如果您有多个工作人员为您的 rails 应用程序服务作为单独的进程运行(例如 puma 可以这样配置),那么每个进程最多可以分配 5 或 10 个连接。如果您使用后台进程(sidekiq 等),它们也可能会使用此数量的连接。

    ConnectionPool 还提供了一个reaper,可用于从 dead 线程中释放分配的数据库连接,但除非您的应用遇到更大的问题,否则这通常无济于事(您的线程idledead 的可能性更大)。

    所以,我会给出一个一般性建议,尝试估计所有 rails 进程可能需要的最大连接数,如果它接近或高于 MySQL 连接限制,请降低连接池大小或减少数量可能运行的 Rails 进程(工作者)。

    如果您需要更多帮助,请指定您使用什么应用程序服务器来运行您的 Rails 应用程序以及它的配置方式,对于任何后台工作人员也是如此。

    【讨论】:

      【解决方案2】:

      尝试在您的 database.yml 文件中设置 reaping_frequency

      reaping_frequency:周期性运行 Reaper 的频率,以秒为单位, 它试图从死线程中查找和恢复连接, 如果程序员忘记在 线程结束或线程意外死亡。不管这 设置时,将在每次阻塞等待之前调用 Reaper。 (默认 nil,表示不调度 Reaper)

      以上文档来自:http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-07
        • 2017-09-09
        • 1970-01-01
        • 2023-04-11
        • 2013-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多