ecshop改造读写主从数据库分离

2016-09-07 22:02 来源:www.chinab4c.com 作者:ecshop专家

设置ecshop数据库服务器分离,让读与写分开 ,可大大加快网站速度。也可更好的优化网站。
data/config.php
 
<?php
 
$db_name   = "ecshop";
 
$prefix    = "ecs_";
 
$timezone    = "Europe/Berlin";
 
$cookie_path    = "/";
 
$cookie_domain    = "";
 
$session = "1440";
 
$_config = array();
 
//数据库主服务器设置, 支持多组服务器设置, 当设置多组服务器时, 则会随机使用某个服务器
$_config['master'][1]['dbhost'] = "192.168.2.175:3306";
$_config['master'][1]['dbname'] = "ecshop";
$_config['master'][1]['dbuser'] = "dragon";
$_config['master'][1]['dbpw'] = "loong";
 
/*
 *$_config['master'][2]['dbhost'] = "";
 *...
 */
 
//数据库从服务器设置( slave, 只读 ), 支持多组服务器设置, 当设置多组服务器时, 系统每次随机使用
$_config['slave'][1]['dbhost'] = "192.168.2.176:3306";
$_config['slave'][1]['dbname'] = "ecshop";
$_config['slave'][1]['dbuser'] = "ivan";
$_config['slave'][1]['dbpw'] = "loong";
 
$_config['slave'][2]['dbhost'] = "192.168.2.177:3306";
$_config['slave'][2]['dbname'] = "ecshop";
$_config['slave'][2]['dbuser'] = "ivan";
$_config['slave'][2]['dbpw'] = "loong";
 
define('EC_CHARSET','utf-8');
 
define('ADMIN_PATH','admin');
 
define('AUTH_KEY', 'this is a key');
 
define('OLD_AUTH_KEY', '');
 
define('API_TIME', '');
 
?>
 
初始化数据连接类
 
 
    /* 初始化数据库类  
     * 如果配置了从服务器,则初始化从库类 
    */  
    if(count($_config['slave'])) {  
        require(ROOT_PATH . 'includes/cls_mysql_slave.php');  
        $db = new cls_mysql_slave($_config);  
    }else{  
        require(ROOT_PATH . 'includes/cls_mysql.php');  
        $db = new cls_mysql($_config);  
    }
增加cls_mysql_slave.php从库类
 
 
<?php
 
require(ROOT_PATH . 'includes/cls_mysql.php');
class cls_mysql_slave extends cls_mysql
{
 var $slaveid = null;
 
 function set_config($config){
 if(!empty($this->config['slave'])) {
 $this->slaveid = array_rand($this->config['slave']);
 }
 parent::set_config($config);
 }
 
 /* 随机分配从库连接 */
 function set_slave_config() { 
 $this->settings = $this->config['slave'][$this->slaveid];
 $this->settings['charset'] = $this->config['charset'];
 $this->settings['pconnect'] = $this->config['pconnect'];
 }
 
 function slave_connect() {
 $this->set_slave_config();
 $dbhost = $this->settings['dbhost'];
 $dbuser = $this->settings['dbuser'];
 $dbpw = $this->settings['dbpw'];
 $dbname = $this->settings['dbname'];
 $this->connect($dbhost, $dbuser, $dbpw, $dbname);
 
 }
 
 
 function query($sql, $type = '') {
 // 如果执行查询操作,则执行从库连接
 if($this->slaveid && strtoupper(substr($sql, 0 , 6)) == 'SELECT') {
 $this->slave_connect();
 }else{
 parent::set_config($this->config);
 $dbhost = $this->settings['dbhost'];
 $dbuser = $this->settings['dbuser'];
 $dbpw = $this->settings['dbpw'];
 $dbname = $this->settings['dbname'];
 $this->connect($dbhost, $dbuser, $dbpw, $dbname);
 }
 return parent::query($sql, $type);
 }
 
 /* 删除失败连接*/
 function del_error_link(){
 unset($this->config['slave'][$this->slaveid]);
 $this->set_config($this->config);
 $this->set_slave_config();
 $dbhost = $this->settings['dbhost'];
 $dbuser = $this->settings['dbuser'];
 $dbpw = $this->settings['dbpw'];
 $dbname = $this->settings['dbname'];
 $this->connect($dbhost, $dbuser, $dbpw, $dbname);
 }
 
}
cls_mysql.php文件类修改
 
 
<?php
 
if (!defined('IN_ECS'))
{
    die('Hacking attempt');
}
 
class cls_mysql
{
    var $link_id    = NULL;
 
    var $settings   = array();
 
    var $queryCount = 0;
    var $linkCount = 0;
    var $queryTime  = '';
    var $queryLog   = array();
 
    var $max_cache_time = 300; // 最大的缓存时间,以秒为单位
 
    var $cache_data_dir = 'temp/query_caches/';
    var $root_path      = '';
 
    var $error_message  = array();
    var $platform       = '';
    var $version        = '';
    var $dbhash         = '';
    var $starttime      = 0;
    var $timeline       = 0;
    var $timezone       = 0;
 
    var $mysql_config_cache_file_time = 0;
 
    var $mysql_disable_cache_tables = array(); // 不允许被缓存的表,遇到将不会进行缓存
    var $config = array();
 
    function __construct($config, $charset = 'utf8', $pconnect = 0, $quiet = 0)
    {
        $this->cls_mysql($config, $charset, $pconnect, $quiet);
    }
 
    function cls_mysql($config, $charset = 'utf8', $pconnect = 0, $quiet = 0)
    {
        if(!empty($config)) {
            $config['charset'] = $charset;
            $config['pconnect'] = $pconnect;
            $this->config = $config;
        }
        
        if (defined('EC_CHARSET'))
        {
            $charset = strtolower(str_replace('-', '', EC_CHARSET));
        }
 
        if (defined('ROOT_PATH') && !$this->root_path)
        {
            $this->root_path = ROOT_PATH;
        }
 
        $this->set_config($this->config);
 
        if ($quiet)
        {
            $dbhost = $this->settings['dbhost'];
            $dbuser = $this->settings['dbuser'];
            $dbpw = $this->settings['dbpw'];
            $dbname = $this->settings['dbname'];
            $this->connect($dbhost, $dbuser, $dbpw, $dbname, $charset, $pconnect, $quiet);
        }
    }
 
    //随机分配数据库连接
    function set_config($config) {
        $sid = array_rand($config['master']);
        $settings = $config['master'][$sid];
        $settings['sid'] = $sid;//www.zuimoban.com
        $settings['charset'] = $this->config['charset'];
        $settings['pconnect'] = $this->config['pconnect'];
        $this->settings = $settings;
    }
 
    function connect($dbhost, $dbuser, $dbpw, $dbname = '', $charset = 'utf8', $pconnect = 0, $quiet = 0)
    {
        if ($pconnect)
        {
            if (!($this->link_id = @mysql_pconnect($dbhost, $dbuser, $dbpw)))
            {
                if (!$quiet)
                {
                    $this->ErrorMsg("Can't pConnect MySQL Server!");
                }
 
                return false;
            }
        }
        else
        {
            if (PHP_VERSION >= '4.2')
            {
                $this->link_id = @mysql_connect($dbhost, $dbuser, $dbpw, true);
            }
            else
            {
                $this->link_id = @mysql_connect($dbhost, $dbuser, $dbpw);
 
                mt_srand((double)microtime() * 1000000); // 对 PHP 4.2 以下的版本进行随机数函数的初始化工作
            }
            if (!$this->link_id)
            {
                if (!$quiet)
                {                  
                    //连接超过10次,中断连接,抛出错误  
                    if($this->linkCount>9){
                        $this->ErrorMsg("Can't Connect MySQL Server!");
                    } 
                    $this->linkCount++;
                    $this->del_error_link();
                }
 
                return false;
            }
        }
 
        $this->dbhash  = md5($this->root_path . $dbhost . $dbuser . $dbpw . $dbname);
        $this->version = mysql_get_server_info($this->link_id);
 
        /* 如果mysql 版本是 4.1+ 以上,需要对字符集进行初始化 */
        if ($this->version > '4.1')
        {
            if ($charset != 'latin1')
            {
                mysql_query("SET character_set_connection=$charset, character_set_results=$charset, character_set_client=binary", $this->link_id);
            }
            if ($this->version > '5.0.1')
            {
                mysql_query("SET sql_mode=''", $this->link_id);
            }
        }
 
        $sqlcache_config_file = $this->root_path . $this->cache_data_dir . 'sqlcache_config_file_' . $this->dbhash . '.php';
 
        @include($sqlcache_config_file);
 
        $this->starttime = time();
 
        if ($this->max_cache_time && $this->starttime > $this->mysql_config_cache_file_time + $this->max_cache_time)
        {
            if ($dbhost != '.')
            {
                $result = mysql_query("SHOW VARIABLES LIKE 'basedir'", $this->link_id);
                $row    = mysql_fetch_assoc($result);
                if (!empty($row['Value']{1}) && $row['Value']{1} == ':' && !empty($row['Value']{2}) && $row['Value']{2} == "\\\\")
                {
                    $this->platform = 'WINDOWS';
                }
                else
                {
                    $this->platform = 'OTHER';
                }
            }
            else
            {
                $this->platform = 'WINDOWS';
            }
 
            if ($this->platform == 'OTHER' &&
                ($dbhost != '.' && strtolower($dbhost) != 'localhost:3306' && $dbhost != '127.0.0.1:3306') ||
                (PHP_VERSION >= '5.1' && date_default_timezone_get() == 'UTC'))
            {
                $result = mysql_query("SELECT UNIX_TIMESTAMP() AS timeline, UNIX_TIMESTAMP('" . date('Y-m-d H:i:s', $this->starttime) . "') AS timezone", $this->link_id);
                $row    = mysql_fetch_assoc($result);
 
                if ($dbhost != '.' && strtolower($dbhost) != 'localhost:3306' && $dbhost != '127.0.0.1:3306')
                {
                    $this->timeline = $this->starttime - $row['timeline'];
                }
 
                if (PHP_VERSION >= '5.1' && date_default_timezone_get() == 'UTC')
                {
                    $this->timezone = $this->starttime - $row['timezone'];
                }
            }
 
            $content = '<' . "?php\\r\\n" .
                       '$this->mysql_config_cache_file_time = ' . $this->starttime . ";\\r\\n" .
                       '$this->timeline = ' . $this->timeline . ";\\r\\n" .
                       '$this->timezone = ' . $this->timezone . ";\\r\\n" .
                       '$this->platform = ' . "'" . $this->platform . "';\\r\\n?" . '>';
 
            @file_put_contents($sqlcache_config_file, $content);
        }
 
        /* 选择数据库 */
        if ($dbname)
        {
            if (mysql_select_db($dbname, $this->link_id) === false )
            {
                if (!$quiet)
                {
                    $this->ErrorMsg("Can't select MySQL database!");
                }
 
                return false;
            }
            else
            {
                return true;
            }
        }
        else
        {
            return true;
        }
    }
 
    ......
 
    /* 删除失败连接*/
    function del_error_link(){
        unset($this->config['master'][$this->settings['sid']]);
        $this->set_config($this->config);
        $dbhost = $this->settings['dbhost'];
        $dbuser = $this->settings['dbuser'];
        $dbpw = $this->settings['dbpw'];
        $dbname = $this->settings['dbname'];
        $this->connect($dbhost, $dbuser, $dbpw, $dbname);
    }
}
 
(责任编辑:chinab4c)