CodeIgniter读写分离实现方法详解(2)

class MY_Controller extends CI_Controller { public function __construct() { parent::__construct(); $this->load->service('common/helper_service', NULL, 'helper'); //下面这段为关闭CI超级对象中的数据库对象和数据库链接,db的对象Codeigniter.php中会关闭 register_shutdown_function(function(){ foreach(get_object_vars($this) as $key => $val) { if(substr($key, 0, 3) == 'db_' && is_object($this->{$key}) && method_exists($this->{$key}, 'close')) { $this->{$key}->close(); } if(substr($key, 0, 5) == 'conn_' && is_resource($this->{$key})) { $this->db->_close($val); unset($this->{$key}); } } }); } } /* End of file MY_Controller.php */ /* Location: ./application/core/MY_Controller.php */

模型中的使用,为了使每个model中都可使用$this->db,以及不多次连接数据库,这里也是将链接放在CI超级对象中。这里就算不读写分离也可以这么处理,可以很方便的连接多个DB,具体的model要使用其他库只需要在构造函数中传入group name即可。

模型调整

public function __construct($group_name = '') { parent::__construct(); $this->initDb($group_name); } private function initDb($group_name = '') { $db_conn_name = $this->getDbName($group_name); $CI = & get_instance(); if(isset($CI->{$db_conn_name}) && is_object($CI->{$db_conn_name})) { $this->db = $CI->{$db_conn_name}; } else { $CI->{$db_conn_name} = $this->db = $this->load->database($group_name, TRUE); } } private function getDbName($group_name = '') { if($group_name == '') { $db_conn_name = 'db'; } else { $db_conn_name = 'db_'.$group_name; } return $db_conn_name; } /* End of file MY_Model.php */ /* Location: ./application/core/MY_Model.php */

最后的数据库配置方式,只需要在原有的基础上配置一个数组即可。是使用双主还是一主多从就看这里的配置方式。最开始想到直接在原配置上加键名来处理,但主与从的对应关系还是没有这样子明了,这里的定义方式决定了load_db_proxy_setting的实现方式。

database.php配置

$_master_slave_relation = array( 'default_master' => array('default_slave1', 'default_slave2', 'default_slave3'), ); /* End of file database.php */ /* Location: ./application/config/database.php */

最开始的数据库链接并未放到CI超级对象中,发现load多个模型时每次都会打开链接,所以完成读写分离之后一定要测试,可以在数据库链接打开和关闭的地方查看是否按预期执行(方法对应application/core/database/drivers/mysql/mysql_driver.php中的db_connect和_close)。整个调整过程最重要的两点就是simple_query方法以及构造函数中关闭数据库链接。模型中的调整是为了更方便的链接多个库,未实现读写分离时也是这么调整的,常用的方法独立成一个文件,MY_Model去继承。

实现MYSQL读写分离的中间件挺多,在没有用到这些时可以通过程序上的控制来实现读写分离。当然这里只是实现了读写分离,可以强制使用主库。如果想要更好的分配方式,可以好好想想load_db_proxy_setting中的分配方式。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/f7a39fb269b76c49edf33f139f2bb741.html