微擎源码分析,主从配置

最近用微擎开发了几个基于微信公众号的项目,分析其主从配置实现方案


首先配置

/data/config.php

<?php
defined('IN_IA') or exit('Access Denied');

$config = array();

$config['db']['master']['host'] = '127.0.0.1';
$config['db']['master']['username'] = 'root';
$config['db']['master']['password'] = 'root';
$config['db']['master']['port'] = '3306';
$config['db']['master']['database'] = 'wq_yiliao';
$config['db']['master']['charset'] = 'utf8';
$config['db']['master']['pconnect'] = 0;
$config['db']['master']['tablepre'] = 'ims_';

$config['db']['slave_status'] = true;
$config['db']['slave']['1']['host'] = '127.0.0.1';
$config['db']['slave']['1']['username'] = 'root';
$config['db']['slave']['1']['password'] = 'root';
$config['db']['slave']['1']['port'] = '3306';
$config['db']['slave']['1']['database'] = 'wq_yiliao';
$config['db']['slave']['1']['charset'] = 'utf8';
$config['db']['slave']['1']['pconnect'] = 0;
$config['db']['slave']['1']['tablepre'] = 'ims_';
$config['db']['slave']['1']['weight'] = 0;

$config['db']['slave_status'] = true;
$config['db']['slave']['2']['host'] = '127.0.0.1';
$config['db']['slave']['2']['username'] = 'root';
$config['db']['slave']['2']['password'] = 'root';
$config['db']['slave']['2']['port'] = '3306';
$config['db']['slave']['2']['database'] = 'wq_yiliao';
$config['db']['slave']['2']['charset'] = 'utf8';
$config['db']['slave']['2']['pconnect'] = 0;
$config['db']['slave']['2']['tablepre'] = 'ims_';
$config['db']['slave']['2']['weight'] = 2;

$config['db']['common']['slave_except_table'] = array('core_sessions');

可以不断增加从库,从库还有权重;有不使用从库的表,core_session,微擎对session有数据库自定义处理,肯定得排除在外


其次对主库还是从库的选择,根据配置走主库还是从库

/framework/function/pdo.func.php


defined('IN_IA') or exit('Access Denied');


function pdo() {
	global $_W;
	static $db;
	if(empty($db)) {
		if($_W['config']['db']['slave_status'] == true && !empty($_W['config']['db']['slave'])) {
			
            load()->classs('slave.db');
			$db = new SlaveDb('master');
		} else {
			load()->classs('db');
			if(empty($_W['config']['db']['master'])) {
				$_W['config']['db']['master'] = $GLOBALS['_W']['config']['db'];
				$db = new DB($_W['config']['db']);
			} else {
				$db = new DB('master');
			}
		}
	}
	return $db;
}


重点就是这个SlaveDb类,继承了Db类,根据规则把主库或者pdo对象返回,重点挑两个方法看

slave_choose 从库权重小算法

init_connect 中的

if(!(!$slave_except && strtoupper(substr($sql, 0 , 6)) === 'SELECT' && $this->slave_connect())) {
  
$this->master_connect();
}


发现了排除表,对于select走从库,其他的走主库

/framework/class/slave.db.class.php

protected function slave_choose(){
		if(!isset($this->weight)) {
			foreach ($this->cfg['slave'] as $key => $value) {
				$this->weight .= str_repeat($key, 1 + intval($value['weight']));
			}
		}
		$sid = $this->weight[mt_rand(0, strlen($this->weight) -1)];
		$this->slaveid = 'slave_' . $sid;
		if(!isset($this->cfg[$this->slaveid])) {
			$this->cfg[$this->slaveid] = $this->cfg['slave'][$sid];
		}
	}

	public function init_connect($sql) {
		if(!($this->cfg['slave_status'] == true && !empty($this->cfg['slave']))) {
			$this->master_connect();
		} else {
			$sql = trim($sql);
			$sql_lower = strtolower($sql);
			$slave_except = false;
			if(!strexists($sql_lower, 'where ')) {
				$tablename = substr($sql_lower, strpos($sql_lower, 'from ') + 5);
			} else {
				$tablename = substr($sql_lower, strpos($sql_lower, 'from ') + 5, strpos($sql_lower, ' where') - strpos($sql_lower, 'from ') - 5);
			}
			$tablename = trim($tablename, '`');
			$tablename = str_replace($this->tablepre, '', $tablename);
			if(!empty($this->cfg['common']['slave_except_table']) && in_array(strtolower($tablename), $this->cfg['common']['slave_except_table'])) {
				$slave_except = true;
			}
            
			if(!(!$slave_except && strtoupper(substr($sql, 0 , 6)) === 'SELECT' && $this->slave_connect())) {
  
				$this->master_connect();
			}
		}
		return true;
	}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值