ruby - 在 puma 工作人员处发生 Sequel::DatabaseDisconnectError,即使 db 在 puma 的 before_fork-hook 中已断开连接
问题描述
我有一个 hanami 1.3 应用程序,但问题应该与 hanami 无关。我想用普通的 Sequel-gem 连接到第二个数据库。因此,我在 hanami's 中定义了连接config/environment.rb
:
# config/environment.rb
# ...
DWH = Sequel.connect(ENV['DWH'], :loggers => [Logger.new($stdout)])
#...
在生产中,我有一个这样的 puma-config:
# config/puma.rb
require_relative './environment'
workers 5
threads_count = 1
threads threads_count, threads_count
daemonize true
preload_app!
rackup DefaultRackup
port 2300
environment 'production'
before_fork do
DWH.disconnect
end
on_worker_boot do
Hanami.boot
end
我用before_fork
钩子断开了数据库(http://sequel.jeremyevans.net/rdoc/files/doc/fork_safety_rdoc.html)。但过了一段时间我得到这样的错误:
Sequel::DatabaseDisconnectError: PG::UnableToSend: SSL SYSCALL error: EOF detected
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/adapters/postgres.rb:166:in `async_exec'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/adapters/postgres.rb:166:in `block in execute_query'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/database/logging.rb:49:in `log_connection_yield'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/adapters/postgres.rb:166:in `execute_query'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/adapters/postgres.rb:153:in `block in execute'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/adapters/postgres.rb:129:in `check_disconnect_errors'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/adapters/postgres.rb:153:in `execute'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/adapters/postgres.rb:515:in `_execute'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/adapters/postgres.rb:327:in `block (2 levels) in execute'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/adapters/postgres.rb:537:in `check_database_errors'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/adapters/postgres.rb:327:in `block in execute'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/database/connecting.rb:301:in `block in synchronize'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/connection_pool/threaded.rb:107:in `hold'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/database/connecting.rb:301:in `synchronize'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/adapters/postgres.rb:327:in `execute'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/dataset/actions.rb:1135:in `execute'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/adapters/postgres.rb:680:in `fetch_rows'
/home/usr/vendor/bundle/ruby/2.6.0/gems/sequel-4.49.0/lib/sequel/dataset/actions.rb:155:in `each'
/home/usr/app/lib/repositories/dwh_repository.rb:39:in `to_a'
解决方案
我与 Sequel 的作者进行了交谈。看来,puma 配置和连接方法是正确的。
似乎,数据库连接被另一个网络部分(即 tcp 超时、防火墙......)丢弃了。
在这种情况下,这是 Sequel 的预期行为:
应用程序失去与数据库的连接。发生这种情况时,会引发 DatabaseDisconnectError 并且 Sequel 从连接池中删除连接。将根据需要创建新连接,直到最大池大小。
解决此问题的最佳方法是修复连接断开的原因(更改设置 [DB,服务器])。一个务实的解决方案可能是将数据库和应用程序放在同一台服务器上。
如果这是不可能的,有一个续集扩展,这可能是一种解决方法: https ://sequel.jeremyevans.net/rdoc-plugins/files/lib/sequel/extensions/connection_validator_rb.html
推荐阅读
- javascript - 我可以在 Express POST 请求中进行 DOM 操作吗?
- python - Discord.py - AttributeError:模块'discord'没有属性'Embed'
- django - 如何使用主管和 gunicorn 或 daphne 运行应用程序 django 频道
- javascript - 在角度 6 中修改数组数据后视图未更新
- python - Keras CNN 中用于多类图像分类的验证精度常数
- python - 无法使用 selenium 和 python 获取 cookie
- java - super(variableName) 之间的区别; 和 super.variableName
- mysql - 为什么 MySQL 将浮点 6.099999904632568 截断为 6.1
- css - 查找用户会员计划 WooCommerce
- python-3.x - 在 Python 中使用 HTTP 客户端库时遇到错误