我在 Rails 应用程序中使用全局变量来存储使用redis gem的 redis 客户端。在 aconfig/initializers/redis.rb
中,我有
$redis = Redis.new(host: "localhost", port: 6379)
然后在应用程序代码中,我$redis
用来处理 Redis 存储中的数据。
我还在生产环境中使用puma作为 Web 服务器,并使用 capistrano 来部署代码。在部署过程中,capistrano 重启 puma。
每次我启动或重新启动 puma web 服务器时,当我第一次使用$redis
访问 Redis 存储中的数据时,总是会收到“内部服务器错误”。我看到了类似的错误Redis::InheritedError (Tried to use a connection from a child process without reconnecting. You need to reconnect to Redis after forking.)
用 google 和 stackoverflow 搜索让我认为在 puma fork 子进程之后我需要重新连接到 Redis。所以,我在我的添加config/puma.rb
:
on_worker_boot do
$redis.ping
end
但我仍然收到由Redis::InheritedError (Tried to use a connection from a child process without reconnecting. You need to reconnect to Redis after forking.)
.
我看到这篇文章http://qiita.com/yaotti/items/18433802bf1720fc0c53。然后我尝试添加config/puma.rb
:
on_restart do
$redis.quit
end
那没有用。
我试着config/initializers/redis.rb
在$redis.ping
之后Redis.new
。那也没有用。
如果 puma 在没有运行 puma 进程的情况下启动,或者在运行 puma 进程的实例时重新启动,我会收到此错误。
刷新页面会让我克服这个错误。但即使在第一次尝试使用$redis
. 我在想我没有使用redis
gem 或正确配置它的重新连接。有人可以告诉我:
- 这是在 Rails 应用程序中使用
redis
gem 的正确方法吗? - 应该如何
redis
重新连接puma
?
puma
gem 文档说,“你应该在这个块中放置关闭全局日志文件、redis 连接等的代码,这样它们的文件描述符就不会泄漏到重新启动的进程中。否则将导致描述符慢慢耗尽并最终由于服务器多次重新启动,因此出现了模糊的崩溃。” 这是在谈论on_restart
街区。但它没有说明应该如何做。