進程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\])
相關文章
相關標籤/搜索