Heroku - ActiveRecord :: ConnectionTimeoutError(无法在5.000秒内获得数据库连接(等待5.000秒))

时间:2014-07-24 13:31:26

标签: ruby-on-rails postgresql heroku exception-handling

我有一个相当简单的应用程序,在本地运行没有问题,但是当部署到heroku时,它会很快停止处理500错误并在日志中出现以下错误:

ActiveRecord::ConnectionTimeoutError (could not obtain a database connection within 5.000 seconds (waited 5.003 seconds))

我进行了搜索,发现this question似乎非常相似。我从这个问题中真的不明白jpeg文件请求的相关性是什么,我不明白给出的答案是什么问题。我可以通过重新启动服务器然后调用多次返回404的页面来重新创建。

我的结果与问题中提到的结果相同(特别是Connections< DB_POOL):

 (staging) $ heroku pg:info --remote staging
=== HEROKU_POSTGRESQL_ONYX_URL (DATABASE_URL)
Plan:        Hobby-dev
Status:      Available
Connections: 5
PG Version:  9.3.4
Created:     2014-05-02 08:57 UTC
Data Size:   9.9 MB
Tables:      11
Rows:        6508/10000 (In compliance)
Fork/Follow: Unsupported
Rollback:    Unsupported

(staging) $ heroku config
.....
DB_POOL:                    10
.....

我基于此railscast开发了我的解决方案,这似乎与其他问题中的方法相同。但是,我不理解这个问题中提供的答案以及它如何适用于我的解决方案如下:  routes.rb中:

match ':status', to: 'errors#show', constraints: {status: /\d{3}/ }, via: :all

application.rb:

config.exceptions_app = self.routes

errorscontroller.rb

class ErrorsController < ApplicationController

    def show
        status = request.path[1..-1]
        case status
        when "404"
            @error = "404 - The page you were looking for cannot be found"
        when "403"
            @error = "403 - The page you were looking for is not accessible"
        when "500"
            @error = "500 - An error occurred within the server"
        end


        respond_to do |format|
            format.html { render action: "error" }
            format.json { render json: {status: status, error: @exception.message} }
        end
    end
end

error.html.erb

<div class='container'>
    <h1 class="errorh1">Oops something went wrong!!</h1>
    <h2 class="errorh2"><%= @error %></h2>
    <br>
    <p>We are sorry. Please <a href='#' data-uv-trigger="contact
">let us know</a> what you were trying to do so that we can look into the problem.</p>
    <br>
    <p>When you are ready to continue, <a href="/">go home</a> to start again.</p>
</div>

注意:我正在运行Rails 4.0.4(和本地的psql(PostgreSQL)9.3.4)

2 个答案:

答案 0 :(得分:2)

我不认为你ErrorsController存在任何问题,无论是你提出它还是使用默认问题,这个问题都会存在。

ActiveRecord::ConnectionTimeoutError只是意味着数据库占用了所有连接,并且它还无法接受任何连接。

可能发生这种情况的原因很少。在某些query transaction中,您可能会花费action的时间。可能是您正在使用像puma这样的多线程服务器或像unicorn这样的多进程服务器(并且您错过了添加所需的配置)。 dead connection也有可能占用资源但不会丢失(完全像deadlock

除非您想将数据库升级到非常大的计划,否则没有解决此问题的关键解决方案。

我建议您添加https://github.com/heroku/rack-timeout,这会在请求(内部数据库需要更长时间响应)时引发Racke::Timeout异常。你可以rescue这个exception或让它保持这种状态。 newrelicairbrake可能会帮助您了解其发生的位置和原因。

我想在大型应用程序中添加一件事,在面向sql transactions的公共场合中也会花费大量时间app/site,但它们会缓存所有这些内容。如果您不介意复杂性,也可以使用redismemcache执行此操作。

最后一件事,如果你找不到解决方案我很害怕,但一定要联系heroku support。他们非常有帮助。

答案 1 :(得分:-1)

增加数据库配置中的池参数。