Rails应用程序:分叉后重新连接juggernaut redis?

时间:2012-06-29 12:47:28

标签: ruby-on-rails redis spawn juggernaut

我正在开发一个使用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仍在访问旧连接。这看起来有可能吗?我如何确保Juggernaut使用新的Redis连接?

如果对我所描述的内容有任何疑问,请与我们联系。我很感激帮助,因为我现在卡住了。

1 个答案:

答案 0 :(得分:0)

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

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

解决方案在this issue中解释。 基本上,他们建议你喜欢memcache explained here

简而言之,在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