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

…衆ロ難τιáo~ 提交于 2020-03-09 19:09:58

在项目中碰到一个问题,以前一直好的程序,增加了些代码,突然爆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里处使用的缓存工具。  

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

分析了前因后果,原因找到了,这个缓存工具初始化的时候就会连接redis,独立进程跑的时候就会加载并连接redis,然后这个进程fork子进程,子进程中如果继续使用这个连接就报错了。  

但是我直接在sneaker worker里面重新设置缓存工具的redis连接,依然报错,这是为何,打开app_cache的源码,发现其连接创建的代码是:


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\])

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!