blob: 42a162b81145179b1b04ccdda99cad4635922d60 [file] [log] [blame]
<?php
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace com\fenqile\fsof\common\file;
use com\fenqile\fsof\common\config\FSOFConstants;
class FSOFRedis
{
private static $_instance;
private $m_redis = null;
private $logger;
private $connect_timeout = 1;
private $read_timeout = 2;
private $retry_count = 1;
private $connect_type = FSOFConstants::FSOF_SERVICE_REDIS_CONNECT_TYPE_TCP;
private $hosts = [
[FSOFConstants::FSOF_SERVICE_REDIS_HOST, FSOFConstants::FSOF_SERVICE_REDIS_PORT],
];
public static function instance($config = [])
{
if (extension_loaded('redis'))
{
if (!isset(FSOFRedis::$_instance))
{
FSOFRedis::$_instance = new FSOFRedis($config);
FSOFRedis::$_instance->get_redis();
}
return FSOFRedis::$_instance;
}
else
{
\Logger::getLogger(__CLASS__)->error("not installed redis extension");
}
return NULL;
}
public function __construct($config = [])
{
$this->logger = \Logger::getLogger(__CLASS__);
if(isset($config['redis_hosts']))
{
$this->hosts = [];
$address = explode(',', $config['redis_hosts']);
foreach ($address as $node){
list($host, $port) = explode(':', $node);
$this->hosts[] = [$host, $port??FSOFConstants::FSOF_SERVICE_REDIS_PORT];
}
}
if(isset($config['redis_connect_timeout']))
{
$this->connect_timeout = $config['redis_connect_timeout'];
}
if(isset($config['redis_read_timeout']))
{
$this->read_timeout = $config['redis_read_timeout'];
}
if(isset($config['redis_connect_type']))
{
$this->connect_type = $config['redis_connect_type'];
}
if(isset($config['redis_retry_count']))
{
$this->retry = min($config['redis_retry_count'], 1);
}
}
public function get_redis()
{
if (!isset($this->m_redis))
{
$hosts_count = count($this->hosts);
$retry = $this->retry_count;
$rand_num = rand() % $hosts_count;
$ret = false;
do{
try{
$redis_cli = new \Redis();
if($this->connect_type == FSOFConstants::FSOF_SERVICE_REDIS_CONNECT_TYPE_TCP)
{
$node = $this->hosts[$rand_num];
$ret = $redis_cli->connect($node[0],$node[1],$this->connect_timeout);
$redis_cli->setOption(\Redis::OPT_READ_TIMEOUT, $this->read_timeout);
$rand_num = ($rand_num + 1)%$hosts_count;
if (!$ret)
{
$this->logger->warn("connect redis failed[{$node[0]}:{$node[1]}]");
}
}else{
$ret = $redis_cli->connect("/var/fsof/redis.sock",-1,FSOFConstants::FSOF_SERVICE_REDIS_PORT,$this->connect_timeout);
}
if($ret)
{
break;
}
}catch (\Exception $e){
$this->logger->error('connect redis excepiton:'.$e->getMessage().', errno:' . $e->getCode());
}
}while($retry-- > 0);
if($ret)
{
$this->m_redis = $redis_cli;
}
else
{
$this->logger->error('connect redis failed:|errno:' . $redis_cli->getLastError());
throw new \Exception("连接redis异常");
}
}
return $this->m_redis;
}
public function getProviderInfo($key)
{
return $this->getlist($key);
}
public function get($key)
{
if (!empty($key) && isset($this->m_redis))
{
return $this->m_redis->get($key);
}
else
{
return NULL;
}
}
public function getlRange($key)
{
if (!empty($key) && isset($this->m_redis))
{
return $this->m_redis->lRange($key, 0, -1);
}
else
{
$this->logger->warn('not object of redis:'.$key);
return NULL;
}
}
public function getlist($key)
{
if (!empty($key) && isset($this->m_redis))
{
try{
return $this->getlRange($key);
}catch (\Exception $e){
$this->logger->warn('redis current connect excepiton'.' |errcode:'.$e->getCode().' |errmsg:'.$e->getMessage());
$this->close();
//重试一次防止连接成功后,连接断开
$this->get_redis();
return $this->getlRange($key);
}
}
else
{
return null;
}
}
public function set($key, $value)
{
if (!empty($key) && isset($this->m_redis))
{
return $this->m_redis->set($key, $value);
}
else
{
return null;
}
}
/**
* Description: 关闭redis连接
*/
public function close()
{
try
{
if (isset($this->m_redis))
{
$this->m_redis->close();
unset($this->m_redis);
}
}
catch (\Exception $e)
{
unset($this->m_redis);
$this->logger->error('close redis error:'.$e->getMessage(),$e);
}
}
public function __destruct()
{
$this->close();
}
}