【发布时间】:2013-09-14 06:25:42
【问题描述】:
我在 Rails 应用程序中使用全局变量来存储使用 redis gem 的 redis 客户端。在config/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
那没用。
我在Redis.new 之后尝试了config/initializers/redis.rb 到$redis.ping。那也没用。
如果 puma 在没有运行 puma 进程的情况下启动,或者在运行 puma 进程的实例时重新启动,我会收到此错误。
刷新页面会让我摆脱这个错误。但即使是第一次尝试使用$redis,我也想摆脱这种情况。我在想我没有使用redis gem 或正确配置它的重新连接。谁能告诉我:
- 这是在 Rails 应用程序中使用
redisgem 的正确方法吗? -
redis连接应该如何在puma中重新连接?
puma gem 文档说,“你应该在这个块中放置关闭全局日志文件、redis 连接等的代码,这样它们的文件描述符就不会泄漏到重新启动的进程中。不这样做会导致缓慢由于服务器多次重新启动,描述符耗尽并最终导致崩溃。”它在谈论on_restart 块。但它没有说明应该如何做。
【问题讨论】:
-
我遇到了同样的错误,无法正常工作。到目前为止你能找到任何答案吗?
-
不,对我来说这仍然是一个未解决的问题。研究了一点,并尝试了一些东西。不幸的是,没有一个工作。
-
还有一个最后的手段来覆盖redis-rb的
ensure_connected-方法,但是我不确定这会有什么副作用
标签: ruby-on-rails redis puma