首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Heroku + Sidekiq: ActiveRecord::StatementInvalid: PG::UnableToSend: SSL系统调用错误:检测到EOF

Heroku + Sidekiq: ActiveRecord::StatementInvalid: PG::UnableToSend: SSL系统调用错误:检测到EOF
EN

Stack Overflow用户
提问于 2013-11-06 09:11:30
回答 1查看 6.5K关注 0票数 18

您好,我们正在Heroku的Cedar堆栈上运行Unicorn和Sidekiq。我们断断续续地得到以下错误

代码语言:javascript
复制
BurnThis ActiveRecord::StatementInvalid: PG::UnableToSend: SSL SYSCALL error: EOF detected

ActiveRecord::StatementInvalid: PG::ConnectionBad: PQconsumeInput() SSL SYSCALL error: Connection timed out

有谁知道这些错误的直接原因是什么?是不是我们的数据库连接太多了?我们已经通过以下方式设置了我们的forking:

unicorn.rb

代码语言:javascript
复制
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 30
preload_app true

before_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::

Base.connection.disconnect!
end

after_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  # other setup
  if defined?(ActiveRecord::Base)
    config = Rails.application.config.database_configuration[Rails.env]
    config['adapter'] = 'postgis'
    config['pool']              = ENV['DB_POOL'] || 5
    config['reaping_frequency'] = ENV['DB_REAP_FREQ'] || 10 # seconds
    ActiveRecord::Base.establish_connection(config)
  end
end

和sidekiq.rb

代码语言:javascript
复制
Sidekiq.configure_server do |config|
  config.redis = { :url => ENV['REDIS_URL'], :namespace => 'btsidekiq' }

  if defined?(ActiveRecord::Base)
    config = Rails.application.config.database_configuration[Rails.env]
    config['adapter'] = 'postgis'
    config['pool']              = ENV['DB_POOL'] || 5
    config['reaping_frequency'] = ENV['DB_REAP_FREQ'] || 10 # seconds
    ActiveRecord::Base.establish_connection(config)
  end
end

Sidekiq.configure_client do |config|
  config.redis = { :url => ENV['REDIS_URL'], :namespace => 'btsidekiq' }
end

我们的数据库池大小是相当大的DB_POOL=100,而且我们使用的PG数据库显然支持500个并发连接。

EN

回答 1

Stack Overflow用户

发布于 2014-03-12 23:39:57

此错误是由您的postgis适配器尝试使用ActiveRecord连接池中的陈旧/失效连接引起的。有两种方法可以解决这个问题:

收割机调整连接池大小以匹配threads/process

  • Lower连接获取频率的数量(
  1. 每N秒检查一次池中的死连接)

要实现#1,您需要为Unicorn和Sidekiq设置合适的池大小,这两个池可能有不同的需求。

Unicorn是单线程的,因此每个进程的5连接的缺省池大小对您来说是正确的。这将为每个WEB_CONCURRENCY后端独角兽工作进程分配最多5个连接。您应重置缺省池大小并使用现有unicorn.rb

代码语言:javascript
复制
$> heroku config:set DB_POOL=5

然而,Sidekiq使用了一个非常不同的模型。默认情况下,Sidekiq只有一个进程和N个线程。您希望DB池大小略大于Sidekiq线程数。您可以在config/initializers/sidekiq.rb中实现此功能,如下所示:

代码语言:javascript
复制
Sidekiq.configure_server do |config|
  pool_size = Sidekiq.options[:concurrency] + 2

  config.redis = { :url => ENV['REDIS_URL'], :namespace => 'btsidekiq', :size => pool_size }

  if defined?(ActiveRecord::Base)
    config = Rails.application.config.database_configuration[Rails.env]
    config['adapter'] = 'postgis'
    config['pool']              = pool_size
    config['reaping_frequency'] = ENV['DB_REAP_FREQ'] || 10 # seconds
    ActiveRecord::Base.establish_connection(config)
  end
end

我最好的猜测是,使用如此大的100个连接池,您更有可能增加无效连接。适当地调整池的大小应该可以解决这个问题。

如果这不起作用,您应该尝试将DB_REAP_FREQ降低到5秒。

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

https://stackoverflow.com/questions/19802233

复制
相关文章

相似问题

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