我司使用的php框架是Yii2。最近因为线上数据库连接爆满,导致线上业务出现异常情况,专门研究了一下Yii的数据库连接问题。1、Yii2如何连接数据库?我们项目使用的是主从分离的mysql数据库。配置中的组件都是用到的,每个数据库的配置都是一个组件。这样就在Yii::$app中注册了数据库的配置,在model中的getDb中可以直接获取数据库的配置信息,如下$config=["components"=>["exam"=>["class"=>"yii\db\Connection",//使用的数据库连接类"charset"=>"utf8",//使用的连接编码方式"enableSchemaCache"=>true,//启用数据库模式缓存"schemaCacheDuration"=>3600,//缓存时间为1小时"username"=>"",//用户名"dsn"=>"","masterConfig"=>[...],//主库配置"masters"=>[],//主库dsn列表"slaveConfig"=>[...],//从库配置,"slaves"=>[],//从库库dsn配置]]];所以我们配置了一个exam数据库,而在实际模型中,master和slave可以使用的数据库配置在这个数据库的基类中:classExamextends\yii\db\ActiveRecord{publicstaticfunctiongetDb(){返回\Yii::$app->考试;}}数据库中的每张表都有自己的模型类,继承这个基类,这样在数据库表中进行的数据库操作就会自动使用这个数据库的配置。同时,在进行数据库操作时,框架会自动将数据库的读写分离,插入、更新、删除操作会使用主库,查询操作会自动使用从库。当需要在主库查询时,也可以使用getDb()->useMaster()从主库查询。获取从库连接时,如果从库连接获取失败,允许获取主库(默认允许自动调整),则自动获取主库连接。2.Yii2什么时候建立连接2.1数据库什么时候建立连接?有两种可能:1、请求到达后,Yii2初始化时建立连接。这是不可能的。我们的项目配置了几十个数据库,不可能每次请求过来都为每个数据库建立连接。这是一种浪费:一方面,一个请求不能使用所有的数据库;另一方面,如果一个数据库连接建立了却没有使用,也是一种数据库资源的浪费。2、在执行数据库模型方法时,只有在使用相应的数据库查询时才会建立与数据库的连接,从而尽可能优化数据库资源的使用。同时,在一次请求中,如果已经建立了数据库连接,则在下次进行类似操作时会重用该数据库连接,减少数据库连接的建立。2.2建立数据库连接的方法建立数据库连接时,底层调用的方法是Yii2\db\Conection类中的openFromPool方法。从方法的名称来看,它从池中打开一个连接。其实这是从之前的配置来看的。从数据库列表中随机获取一个连接:protectedfunctionopenFromPool(array$pool,array$sharedConfig){if(empty($pool)){returnnull;}if(!isset($sharedConfig['class'])){$sharedConfig['class']=get_class($this);$cache=is_string($this->serverStatusCache)?Yii::$app->get($this->serverStatusCache,false):$this->serverStatusCache;//这里会先打乱从库的地址列表,然后循环配置列表逐一建立连接,直到建立连接成功。如果建立失败,则返回nullshuffle($pool);foreach($poolas$config){...try{//这里是建立连接的实际方法$db->open();返回$db;}}返回空值;这里有一点需要注意。调用openFromPool建立连接时,底层实际使用的方法是open。这里需要注意的是,获取从库时,是使用生成的$db对象创建的,而获取主库时直接使用$this,所以在open方法中,会判断是否有$this->masters,只有在主库中有值时,才会建立与主库的连接。一开始以为每次都是建立主库连接。直到看到$db,我才意识到它不是原来的Connection对象。3、Yii2什么时候会销毁链接?上面说了,我们只有在执行数据库表对应的模型文件的方法时才建立数据库连接,而数据库的连接会放在db对象中,从库会放在_slave中,主库的连接放在pdo中。这样获取的时候,如果有值,就直接使用。具体销毁是在PHP请求完成后,PHP将返回值发送给nginx,PHP释放相关对象值。最后,建议在使用Yii2时使用主从数据库配置,这样可以减轻主服务器的压力,避免主服务器出现问题。同时,如果查询压力过大,可以轻松扩容从库,增加系统。抗压性。
