常驻内存PHPswoole程序redis丢失长连接怎么解决?

大神好:我用ESD框架 开发了一个websocket服务,redis,mysql都是连接池实来的,esd框架虽并不完善但也做了连接超时断开后,再次使用上连接时会重连,但发现一夜过后(也就是长达7,8个小时没有人使用)redis长连接重连时失败了。报如下错误:
read error on connectionNOAUTH Authentication required. 后面这个其实是密码没认证而已,但明显配置是没问题的,只要我重启服务,问题就没有了。
可是不可能靠重启解决问题。 我看了下redis服务器的配置,连接空闲断开的选项是没有启用的,也就是说redis都是长连接。客户端也是使用了不超时选项的。下面这获取redis连接的方法,重点是这一行:$db->setOption(\Redis::OPT_READ_TIMEOUT, -1); 是不会超时的:

    /**
     * @return \Redis
     * @throws RedisException
     */
    public function db(): Redis
    {
        $db = getContextValue("Redis:{$this->getRedisConfig()->getName()}");
        if ($db == null) {
            $db = $this->pool->pop();
            if($db instanceof Redis){
               if(!$db->isConnected()){
                   if(!$db->connect($this->redisConfig->getHost(),$this->redisConfig->getPort())){
                       throw new RedisException($db->getLastError());
                   }
                   $db->setOption(\Redis::OPT_READ_TIMEOUT, -1);
                   if(!empty($this->redisConfig->getPassword())){
                       if(!$db->auth($this->redisConfig->getPassword())){
                           throw new RedisException($db->getLastError());
                       }
                   }
                   $db->select($this->redisConfig->getSelectDb());
               }
            }
            defer(function () use ($db) {
                $this->pool->push($db);
            });
            setContextValue("Redis:{$this->getRedisConfig()->getName()}", $db);
        }
        return $db;
    }

但还是出现了开头说的那种错误, 是什么原因?如何解决?

阅读 2.1k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题