postgres - Heroku+Sidekiq: ActiveRecord:: StatementInvalid: PG:: UnableToSend: SSL SYSCALL error: Se detectó EOF
heroku reset database (1)
Hola, estamos corriendo en la pila de cedros de Heroku con Unicorn y Sidekiq. Recibimos intermitentemente los siguientes errores.
BurnThis ActiveRecord::StatementInvalid: PG::UnableToSend: SSL SYSCALL error: EOF detected
ActiveRecord::StatementInvalid: PG::ConnectionBad: PQconsumeInput() SSL SYSCALL error: Connection timed out
¿Alguien tiene alguna idea de cuál es la causa directa de estos errores? ¿Son demasiadas conexiones a nuestra base de datos? Ya tenemos nuestra horquilla configurada de la siguiente manera:
unicorn.rb
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
Y sidekiq.rb
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
El tamaño de nuestro grupo de bases de datos es bastante grande DB_POOL = 100 y estamos en una base de datos PG que aparentemente soporta 500 conexiones al mismo tiempo.
Este error se debe a que su adaptador de postgis
intenta usar una conexión obsoleta / muerta del grupo de conexión ActiveRecord. Hay dos formas de abordar este problema:
- Tamaño de su grupo de conexiones para que coincida con el número de hilos / proceso
- Baja frecuencia de cosecha de la conexión (Reaper verifica el conjunto en busca de conexiones muertas, cada N segundos)
Para implementar el número 1, debe configurar el tamaño de su grupo de manera adecuada para Unicorn y para Sidekiq, que probablemente tengan diferentes necesidades.
Unicornio es un solo hilo, por lo que el tamaño de grupo predeterminado de 5
conexiones por proceso es correcto para usted. Esto asignará hasta 5 conexiones para cada uno de los trabajadores WEB_CONCURRENCY
backend de WEB_CONCURRENCY
. Debe restablecer el tamaño de grupo predeterminado y usar su unicorn.rb
existente:
$> heroku config:set DB_POOL=5
Sin embargo, Sidekiq utiliza un modelo muy diferente. Por defecto, Sidekiq tiene un proceso único y N hilos. Desea un tamaño de grupo de DB un poco más grande que el número de subprocesos de Sidekiq. Puede implementar esto en su config/initializers/sidekiq.rb
siguiente manera:
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
Mi mejor conjetura es que al usar un grupo tan grande de 100 conexiones, es más probable que acumules conexiones muertas. El tamaño adecuado de la piscina debería solucionar este problema.
Si esto no funciona, debería intentar reducir su DB_REAP_FREQ
a 5 segundos.