Redis.class.php 3.9 KB
<?php
class Util_Server_Adapter_Cache_Redis implements Util_Server_Adapter_Interface {
     
    /**
     * 配置文件中有关redis的主配置段
     */
    const SECTION_MASTER = 'redis-master'; 
    
     /**
     * 配置文件中有关redis的从配置段
     */
    const SECTION_SLAVE = 'redis-slave-';
    
    const PRENAME = 'servers';
    const TIMEOUT = 30;    
    private $_master_section = null;
    
    public function __construct($options = null) {
        if (! extension_loaded ( 'redis' ))
            throw new Util_Server_Exception ( get_class ( $this ) . ':load redis module first please!' );
        if(!empty($options)) {
            $this->_master_section = self::SECTION_MASTER;
        }
        $this->_config = Util_Common_Core::loadCacheMem ();
    }
    public function __destruct() {
    }
    
    /**
     * 得到可用文件服务器的配置host, port列表
     * 
     * @return array or false
     * array('master'=>array(array('host','port')),'slave'=>array('host1'=>array('host','port')))
     */
    public function loadBalanceServer() {
        $return = $this->loadServers ();
        return empty ( $return ) ? false : $return;
    }
    
    /**
     * 读取Mogile服务器列表,配置中格式:定义再mogilefs段,格式为:192.168.4.133:6001,192.168.4.134:6001
     *
     * @param string $filename
     * @return array
     */
    public function loadServers() {
        
        $svrobj = Util_Common_Core::loadConfig ( $this->_config, $this->_master_section);
        $masters =  $this->_getServersFromString ( str_replace ( ' ', '', $svrobj->{self::PRENAME} ) );
        $servers = array('master'=>array(),'slave'=>array());
        if(empty($masters)) {
            $servers = array();
        }
        foreach($masters as $master) {
            $section = self::SECTION_SLAVE.$master['host'].'-'.$master['port'];
            $slaveobj = Util_Common_Core::loadConfig ( $this->_config, $section );
            $slaves = $this->_getServersFromString ( str_replace ( ' ', '', $slaveobj->{self::PRENAME} ) );
            $servers['master'][] = $master;
            $servers['slave'][$master['host'].'-'.$master['port']] = $slaves;
        }
        return $servers;
    }
    
    /**
     * 检查服务器是否正常
     *
     * @param string $host 192.168.4.133
     * @return true or string true 代表正常字符串为出错信息 
     */
    private function _checkServer($host, $port) {
        $errno = 0;
        $errstr = '';
        $fs = @fsockopen ( $host, $port, $errno, $errstr, self::TIMEOUT );
        if (is_resource($fs)) {
            @fclose ( $fs );
            return true;
        } else {
            $log = sprintf("%s:%s redis down at time: %s\n", $host, $port, date('Y-m-d H:i:s',time()));
            file_put_contents ( dirname ( __FILE__ ) . '/redis.down.log', $log);
            return false;
        }
    }
    
    /**
     * 分析取得的服务器字符串,得到服务器配置数组
     *
     * @param string $svrstring
     * @return array
     */
    private function _getServersFromString($svrstring) {
        if ($svrstring == '')
            throw new Util_Server_Exception ( get_class ( $this ) . ':服务器配置字符串为空!' );
        $tmpary = array_unique ( explode ( ',', $svrstring ) );
        if (count ( $tmpary ) == 0)
            throw new Util_Server_Exception ( get_class ( $this ) . ':服务器配置字符串格式错误' );
        $return = array ();
        $counter = count ( $tmpary );
        for($i = 0; $i < $counter; $i ++) {
            if (($tmp = parse_url ( $tmpary [$i] )) !== false && $this->_checkSvrAry ( $tmp ))
                $return [] = $tmp;
        }
        return $return;
    }
    
    /**
     * 测试服务器配置数组是否格式正常
     *
     * @param array $ary
     * @return boolean
     */
    private function _checkSvrAry(array $ary) {
        return isset ( $ary ['host'] ) && isset ( $ary ['port'] );
    }
}