CodeIgniter 3.0支持数据库读写分离方式

Posted 雨沐风

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeIgniter 3.0支持数据库读写分离方式相关的知识,希望对你有一定的参考价值。

网上有部分方法,支持读写分离,但过于复制,而且有的只支持2.0版本的,现在改善一个,支持3.0版本的读写分离

本次修改的环境是:

步骤一:修改application/config/database.php

数据库读、写连接参数的配置。

$active_group = ‘default‘;
$query_builder = TRUE;
$db[‘default‘] = array(
    ‘dsn‘    => ‘‘,
    ‘hostname‘ => ‘127.0.0.1‘,
    ‘username‘ => ‘root‘,
    ‘password‘ => ‘‘,
    ‘database‘ => ‘xxx‘,
    ‘dbdriver‘ => ‘mysqli‘,
    ‘dbprefix‘ => ‘‘,
    ‘pconnect‘ => FALSE,
    ‘db_debug‘ => 1,
    ‘cache_on‘ => FALSE,
    ‘cachedir‘ => ‘‘,
    ‘char_set‘ => ‘utf8‘,
    ‘dbcollat‘ => ‘utf8_general_ci‘,
    ‘swap_pre‘ => ‘‘,
    ‘encrypt‘ => FALSE,
    ‘compress‘ => FALSE,
    ‘stricton‘ => FALSE,
    //failover 配置备用节点
    ‘failover‘ => array(
        /* 设置多个备用数据库主机
         * array(
            ‘hostname‘ => ‘localhost1‘,
            ‘username‘ => ‘‘,
            ‘password‘ => ‘‘,
            ‘database‘ => ‘‘,
            ‘dbdriver‘ => ‘mysqli‘,
            ‘dbprefix‘ => ‘‘,
            ‘pconnect‘ => TRUE,
            ‘db_debug‘ => TRUE,
            ‘cache_on‘ => FALSE,
            ‘cachedir‘ => ‘‘,
            ‘char_set‘ => ‘utf8‘,
            ‘dbcollat‘ => ‘utf8_general_ci‘,
            ‘swap_pre‘ => ‘‘,
            ‘encrypt‘ => FALSE,
            ‘compress‘ => FALSE,
            ‘stricton‘ => FALSE
        ),
        array(
            ‘hostname‘ => ‘localhost2‘,
            ‘username‘ => ‘‘,
            ‘password‘ => ‘‘,
            ‘database‘ => ‘‘,
            ‘dbdriver‘ => ‘mysqli‘,
            ‘dbprefix‘ => ‘‘,
            ‘pconnect‘ => TRUE,
            ‘db_debug‘ => TRUE,
            ‘cache_on‘ => FALSE,
            ‘cachedir‘ => ‘‘,
            ‘char_set‘ => ‘utf8‘,
            ‘dbcollat‘ => ‘utf8_general_ci‘,
            ‘swap_pre‘ => ‘‘,
            ‘encrypt‘ => FALSE,
            ‘compress‘ => FALSE,
            ‘stricton‘ => FALSE
        )*/
    ),
    ‘save_queries‘ => TRUE
);

//开启 $db[‘write‘] 支持读写分离

$db[‘write‘] = array(
    ‘dsn‘    => ‘‘,
    ‘hostname‘ => ‘127.0.0.1‘,
    ‘username‘ => ‘root‘,
    ‘password‘ => ‘‘,
    ‘database‘ => ‘xxx‘,
    ‘dbdriver‘ => ‘mysqli‘,
    ‘dbprefix‘ => ‘‘,
    ‘pconnect‘ => FALSE,
    ‘db_debug‘ => 1,
    ‘cache_on‘ => FALSE,
    ‘cachedir‘ => ‘‘,
    ‘char_set‘ => ‘utf8‘,
    ‘dbcollat‘ => ‘utf8_general_ci‘,
    ‘swap_pre‘ => ‘‘,
    ‘encrypt‘ => FALSE,
    ‘compress‘ => FALSE,
    ‘stricton‘ => FALSE,
    //failover 配置备用节点
    ‘failover‘ => array(),
    ‘save_queries‘ => TRUE
);

步骤二、修改 system/core/Controller.php 加入下列代码

public $db_write = null;

步骤三、修改system/database/DB.php

找到 

$DB->initialize();

在上面加入

//支持 读写分离
    if (!empty($db[‘write‘])){
        $CI =& get_instance();
        $CI->db_write = new $driver($db[‘write‘]);
        $DB->is_single_instance = false;
        $CI->db_write->is_single_instance = false;
        $CI->db_write->initialize();
    }else{
        $DB->is_single_instance = true;
    }

步骤四、修改 system/database/DB_driver.php

添加对SQL的数据库连接选择路由功能。

添加实例变量

public $is_single_instance = false;

并替换下面的方法

public function simple_query($sql)
    {
        if ( ! $this->conn_id)
        {
            $this->initialize();
        }
        if($this->is_single_instance){
            //不读写分离
            return $this->_execute($sql);
        }else{
            //读写分离
            if(preg_match("/^\s*select/",strtolower($sql)))
            {
                return $this->_execute($sql);
            }
            else
            {
                $CI =& get_instance();
                //默认选择主库!这点很重要,如果有未知功能也可以保证数据完整
                $rrr = $CI->db_write->_execute($sql);
                return $rrr;
            }
        }
    }

第五骤:如果是使用默认的 mysqli连接,请注释掉 system/database/drivers/mysqli/mysqli_driver.php 的下面方法

public function insert_id(){
return $this->conn_id->insert_id;

}

并在  system/database/DB_driver.php  里面新增下方法

/**
     * Insert ID
     *
     * @return    int
     */
    public function insert_id()
    {
        //return $this->conn_id->insert_id;
        if($this->is_single_instance){
            return $this->conn_id->insert_id;
        }else{
            //读写分离
            $CI =& get_instance();
            return $CI->db_write->conn_id->insert_id;
        }
    }

第六步:修改 system/database/DB_driver.php 里面的 close方法

/**
     * Close DB Connection
     *
     * @return    void
     */
    public function close()
    {
        if($this->is_single_instance){
            if ($this->conn_id)
            {
                $this->_close();
                $this->conn_id = FALSE;
            }
        }else{
            //读写分离
            $CI =& get_instance();
            $CI->db_write->conn_id = FALSE;
            $this->conn_id = FALSE;
        }
    }

至此,CodeIgniter 3.0 完美的解决了 读写分离的操作

本文参考了部分网上的资源

 

 

 






以上是关于CodeIgniter 3.0支持数据库读写分离方式的主要内容,如果未能解决你的问题,请参考以下文章

akka-typed - CQRS读写分离模式

Spring实现动态数据源,支持动态加入删除和设置权重及读写分离

服务读写分离(读服务,写服务),是否可行?

服务读写分离架构,绝不推荐

(VIP-朝夕教育)2021-05-31 .NET高级班 30-数据库设计(SqlServer读写分离对等发布)

FreeSql (三十)读写分离