0

我正在开发一个使用Juggernaut定期向客户端推送数据的 Rails 应用程序。我使用控制器动作来开始推送;但由于推送通常是一个漫长的过程(10 分钟或更长时间),我使用 spawn 来分叉任务。例如:

def start_pushing
  spawn_block(:argv => "juggernaut-pushing") do
    for x in y
      Juggernaut.publish(stuff in here)
      sleep(30) # delay before publishing next item
    end
  end
end

问题是当我点击 start_pushing 操作时,我在日志文件中发现了这个错误:

spawn> Exception in child[27898] - Redis::InheritedError: Tried to use a connection from a child process without reconnecting. You need to reconnect to Redis after forking.

所以我在 spawn_block 中添加了以下内容,希望它能解决问题:

    require 'redis'
    $redis.client.disconnect
    $redis = Redis.new(:host => 'localhost', :port => 6379)

它似乎没有解决它,尽管即使在我将它添加到重置 $redis 之前,该操作一直在间歇性地工作。我在想也许重置 $redis 并没有做任何事情。剑圣仍在访问旧连接。这看起来有可能吗?我如何确保 Juggernaut 使用新的 Redis 连接?

请让我知道有关我所描述内容的任何问题。感谢您的帮助,因为我现在陷入困境。

4

1 回答 1

0

问题在于使用全局(以 $ 开头的变量)并使用乘客。所有全局变量在所有乘客进程中共享。Redis 进行了某种检查,以确保 redis 调用的进程 ID 与连接的进程 ID 相同。因此,如果 redis 使用乘客 worker 1 连接,但随后 worker 2 使用它,则会出现此错误。

有关详细信息,请参阅 Redis::Client 类的 connect 和 ensure_connected 方法。

这个问题解释了解决方案。基本上,他们建议您确实喜欢这里解释的 memcache 。

简而言之,在您的 config/environement.rb 中,添加以下内容:

if defined?(PhusionPassenger)
    PhusionPassenger.on_event(:starting_worker_process) do |forked|
        if forked
            # We're in smart spawning mode.
            $redis.reconnect
        else
            # We're in conservative spawning mode. We don't need to do anything.
        end
    end
end
于 2012-10-04T13:46:23.130 回答