简体   繁体   English

Rails应用:分叉后重新连接剑圣redis吗?

[英]Rails app: Reconnect juggernaut redis after forking?

I'm working on a Rails app that is using Juggernaut to push data to clients at regular intervals. 我正在使用Rails应用程序,该应用程序使用Juggernaut定期将数据推送到客户端。 I use a controller action to get the pushing started; 我使用控制器动作来开始推送; but since the pushing is often a long process (10 minutes or more), I am using spawn to fork the task. 但是由于推送通常是一个漫长的过程(10分钟或更长时间),因此我使用spawn来分叉任务。 For example: 例如:

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

The problem is that I find this error in the log file when I hit the start_pushing action: 问题是,当我按下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.

So I added the following right inside the spawn_block, hoping it would fix the problem: 因此,我在spawn_block中添加了以下内容,希望它可以解决此问题:

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

It didn't seem to fix it, though the action has been working intermittently even before I added this to reset $redis. 它似乎并没有解决它,尽管该动作在我添加此操作以重置$ redis之前就已经间歇性地工作了。 I'm thinking that perhaps resetting $redis isn't doing anything; 我在想,也许重置$ redis不会做任何事情。 Juggernaut is still accessing an old connection. 剑圣仍在访问旧的连接。 Does that seem likely? 看来有可能吗? How would I make sure that Juggernaut uses a new Redis connection? 我如何确保剑圣使用新的Redis连接?

Please let me know of any questions about what I'm describing. 如果您对我的描述有任何疑问,请告诉我。 I appreciate the help, because I'm stuck right now. 感谢您的帮助,因为我现在被困住了。

The problem is using a global (variable that begins with $) and using Passenger. 问题是使用全局变量(以$开头的变量)和乘客。 All globals are shared accross ALL passenger processes. 所有全球旅客在所有旅客流程中都是共享的。 Redis has some kind of check to make sure the process ID of the redis call is the same one as the one that connected. Redis进行某种检查以确保redis调用的进程ID与连接的ID相同。 So if redis was connected using the passenger worker 1 but then worker 2 uses it, it will give this error. 因此,如果使用乘客工作人员1连接了redis,但是工作人员2使用了redis,则会出现此错误。

See the method connect and ensure_connected of the Redis::Client class for more information. 有关更多信息,请参见Redis :: Client类的connect和sure_connected方法。

The solution is explained in this issue . 此问题中说明了解决方案。 Basically, they suggest that you do like memcache as explained here . 基本上,他们建议您像这里介绍的那样喜欢memcache。

In short, in your config/environement.rb, add the following: 简而言之,在您的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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM