【问题标题】:Releasing ActiveRecord connection before the end of a Sidekiq job在 Sidekiq 作业结束之前释放 ActiveRecord 连接
【发布时间】:2014-07-09 20:42:27
【问题描述】:

这个问题涉及性能和优化问题,以及实现 Sidekiq 作业的方式。

假设我们有以下工作流程

默认执行

# Step 1
do_things_with_activerecord_db_and_get_some_parameters()

# Step 2
step2_perform_an_http_request_with_these_parameters_on_unreliable_server()

结束

在以下情况下,ActiveRecord 连接在步骤 1 中从池中取出,只有在 SideKiq 的 ActiveRecord 中间件完成(或失败)作业后才会由 SideKiq 释放。

由于我们在第2步请求的外部http服务器不可靠,http请求可能需要很长时间甚至超时,因此ActiveRecord连接一直被锁定,对吧?

所以我的问题是:调用是否相关、有用且安全:

ActiveRecord::Base.clear_active_connections!

在步骤 1 和步骤 2 之间,以便作业自行释放资源并使其可用于其他类似作业?还是我错过了一些关于连接池的东西?这种方法也可以应用于redis连接吗?

提前致谢!

【问题讨论】:

    标签: ruby-on-rails ruby activerecord connection sidekiq


    【解决方案1】:

    你肯定想调用 clear_active_connections!。

    我们在使用 TorqueBox 服务器上的 JMS 的环境中运行 ActiveRecord,并且我们必须执行类似的操作以确保释放连接。

    需要注意的是,如果您生成一个使用 ActiveRecord 的线程,您也需要这样做,因为(当然在 ActiveRecord 3.2 中)线程 ID 被用作连接检查过程的一部分。

    我们反复使用的模式如下:

    def with_connection(&block)
      ActiveRecord::Base.connection_pool.with_connection do
        yield block
      end
    ensure
      ActiveRecord::Base.clear_active_connections!
      ActiveRecord::Base.connection.close
    end
    

    你可以这样使用:

    with_connection do 
      do_things_with_activerecord_db_and_get_some_parameters()   
    end
    

    【讨论】:

    • 使用 with_connection 是正确的做法。不需要您的确保块。
    • @MikePerham 即使在使用 with_connection 时,我们在 JMS 消息处理器中始终泄漏连接后,添加了确保块。
    • 非常感谢你们两位提供这些非常明确的答案,这对我来说很有意义。我借此机会感谢并祝贺 Mike 的出色框架。
    猜你喜欢
    • 2014-05-31
    • 2023-03-15
    • 1970-01-01
    • 2016-11-17
    • 1970-01-01
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    • 2021-03-19
    相关资源
    最近更新 更多