进程fork状况下使用redis的问题

在项目中碰到一个问题,之前一直好的程序,增长了些代码,忽然爆redis异常:redis

Tried to use a connection from a child process without reconnecting. You need to reconnect to Redis after forking.

意思很明确,就是你fork了进程,子进程中的redis链接无法用了,要重连。可是为何呢。  缓存

项目是rails的,一直没有问题,有独立跑的进程,这个进程会先加载rails环境,而后运行sneaker worker,错误就是在从sneaker worker里面爆出来的,在里面会使用配置在rails initializer里处使用的缓存工具。  app

缓存工具是同事写的第三方的gem包app_cache,在initializer里面初始化。工具

分析了来龙去脉,缘由找到了,这个缓存工具初始化的时候就会链接redis,独立进程跑的时候就会加载并链接redis,而后这个进程fork子进程,子进程中若是继续使用这个链接就报错了。  url

可是我直接在sneaker worker里面从新设置缓存工具的redis链接,依然报错,这是为什么,打开app_cache的源码,发现其链接建立的代码是:code

redis = Redis.current.nil? ? Redis.new(:url => options\[:url\]) : Redis.current

问题就出在Redis.current上面,由于是进程fork,子进程的Redis.current并不为nil,此时就会使用这个链接,可是很显然这个链接是父进程建立的,这里是无效的,若是要去使用,就会报开始那个异常。  进程

解决起来很简单,改下app_cache,把连接建立代码改成以下:源码

redis = Redis.new(:url => options\[:url\])
相关文章
相关标签/搜索