php實(shí)現(xiàn)mysql連接池效果實(shí)現(xiàn)代碼
循環(huán)從mysql連接池中獲取連接,不需要重復(fù)創(chuàng)建新的連接。
參考配置修改:可以參考下面的文章
防止訪問(wèn)量過(guò)大,把連接數(shù)占滿了
<?php /** * @author xuleyan * @title mysql類 */ class DbHelper{ //連接池 private $_pools = []; //連接池大小 const POOLSIZE = 5; const USERNAME = "root"; const PASSWORD = "root"; const HOST = "127.0.0.1"; const DB = "test"; public function __construct() { $db = self::DB; $username = self::USERNAME; $password = self::PASSWORD; $host = self::HOST; //持久化連接 $presistent = array(PDO::ATTR_PERSISTENT => true); for ($i=0; $i < self::POOLSIZE; $i++) { $connection = new PDO("mysql:dbname=$db;host=$host", $username, $password); // sleep(3); array_push($this->_pools, $connection); } } //從數(shù)據(jù)庫(kù)連接池中獲取一個(gè)數(shù)據(jù)庫(kù)鏈接資源 public function getConnection() { echo 'get' . count($this->_pools) . "<br>"; if (count($this->_pools) > 0) { $one = array_pop($this->_pools); echo 'getAfter' . count($this->_pools) . "<br>"; return $one; } else { throw new ErrorException ( "<mark>數(shù)據(jù)庫(kù)連接池中已無(wú)鏈接資源,請(qǐng)稍后重試!</mark>" ); } } //將用完的數(shù)據(jù)庫(kù)鏈接資源放回到數(shù)據(jù)庫(kù)連接池 public function release($conn) { echo 'release' . count($this->_pools) . "<br>"; if (count($this->_pools) >= self::POOLSIZE) { throw new ErrorException ( "<mark>數(shù)據(jù)庫(kù)連接池已滿!</mark>" ); } else { array_push($this->_pools, $conn); // $conn = null; echo 'releaseAfter' . count($this->_pools) . "<br>"; } } public function query($sql) { try { $conn = $this->getConnection(); $res = $conn->query($sql); $this->release($conn); return $res; } catch (ErrorException $e) { print 'error:' . $e->getMessage(); die; } } public function queryAll($sql) { try { $conn = $this->getConnection(); $sth = $conn->prepare($sql); $sth->execute(); $result = $sth->fetchAll(); return $result; } catch (PDOException $e) { print 'error:' . $e->getMessage(); die; } } }
在另外的文件這樣調(diào)用
<?php require_once 'db.php'; $sql = 'select * from user'; $dbhelper = new DbHelper; for ($i=0; $i < 10; $i++) { $res = $dbhelper->query($sql); // var_dump($res) . PHP_EOL; }
ThinkPHP連接MySQL的連接池使用方法
因?yàn)橐粋€(gè)小bug,導(dǎo)致項(xiàng)目在某個(gè)晚上向mysql發(fā)送了大量的連接請(qǐng)求,同時(shí)mysql服務(wù)器的dns出現(xiàn)問(wèn)題,導(dǎo)致反解超時(shí)。最后活活的把mysql服務(wù)器拖掛了。
最后bug修復(fù)了,并研究了一下增加 mysql連接池的辦法。
這兩天搜了一下,發(fā)現(xiàn)ThinkPHP文檔里沒(méi)有連接池的相關(guān)文檔。所以自己研究了下代碼。
首先: PHP常用的mysql擴(kuò)展庫(kù)有三種 : mysql, mysqli, pdo_mysql.
* mysqli 是不支持連接池的。
* pdo_mysql 支持,但是,thinkPHP的pdo擴(kuò)展不支持mysql,僅支持:'MSSQL','ORACLE','Ibase','OCI' . ( 見(jiàn) Pdo.class.php 的第59行)
* mysql 支持,通過(guò)方法:mysql_pconnect . (具體參數(shù)可以看php官方文檔)
1 使ThinkPHP啟用 長(zhǎng)連接的方式是:
class BaseMysql extends Model { protected $connection = array( 'db_type' => 'mysql', 'db_user' => '***', 'db_pwd' => '*******', 'db_host' => '*******', 'db_port' => '3306', 'db_name' => 'custom', 'db_params' => array('persist' => true), ); }
如果你認(rèn)為,配置這個(gè)就萬(wàn)事大吉了,那就大錯(cuò)特錯(cuò)了。
2 mysql -> my.cnf修改配置:
[mysqld]
interactive_timeout =60 // 交互連接(mysql-client)的過(guò)期時(shí)間。
wait_timeout =30 // 長(zhǎng)連接的過(guò)期時(shí)間時(shí)間。 這個(gè)一定要改啊!默認(rèn)是8個(gè)小時(shí)。 如果請(qǐng)求量大點(diǎn),很快連接數(shù)就占滿了。
max_connections = 100 //最大連接數(shù),可以認(rèn)為是連接池的大小
3 php.ini 修改:
[MySql]
mysql.allow_persistent = On
mysql.max_persistent = 99 // 要小于mysql配置的最大連接數(shù)
mysql.max_links = 99
4 webserver如果是apache ,需要啟用keep-alive。 否則,一旦請(qǐng)求退出,長(zhǎng)連接將無(wú)法再重用。
webserver 是nginx的情況:
pm = dynamic // 默認(rèn)啟動(dòng)一些子進(jìn)程,用于處理http請(qǐng)求。
pm.max_children // 最大的子進(jìn)程數(shù)。 這個(gè)配置要小于 mysql 的max_connections。
5 如果發(fā)現(xiàn)還是不能用,請(qǐng)檢查操作系統(tǒng)的keepalive 是否啟用。
綜述:
需要 keep-alive 和 數(shù)據(jù)庫(kù)長(zhǎng)連接同時(shí)啟用,否則長(zhǎng)連接回白白的占用mysql的連接數(shù)資源,而無(wú)法重用。
對(duì)于 nginx + php-fpm 的情況,其實(shí)是保持了 php-fpm 子進(jìn)程與mysql的長(zhǎng)連接。 前端的http請(qǐng)求被分配給哪個(gè) php-fpm子進(jìn)程,該子進(jìn)程就重用自己與mysql 的長(zhǎng)連接。
上述是一整天的研究結(jié)果,不完備的地方,請(qǐng)大家指出,在此先行謝過(guò)!
- workerman寫mysql連接池的實(shí)例代碼
- 詳解Spring Boot Mysql 版本驅(qū)動(dòng)連接池方案選擇
- Python 使用 PyMysql、DBUtils 創(chuàng)建連接池提升性能
- Node.js使用MySQL連接池的方法實(shí)例
- nodeJs實(shí)現(xiàn)基于連接池連接mysql的方法示例
- Node.js實(shí)現(xiàn)mysql連接池使用事務(wù)自動(dòng)回收連接的方法示例
- Python MySQL數(shù)據(jù)庫(kù)連接池組件pymysqlpool詳解
- Java使用MySQL實(shí)現(xiàn)連接池代碼實(shí)例
相關(guān)文章
mysql 中InnoDB和MyISAM的區(qū)別分析小結(jié)
InnoDB和MyISAM是在使用MySQL最常用的兩個(gè)表類型,各有優(yōu)缺點(diǎn),視具體應(yīng)用而定?;镜牟顒e為:MyISAM類型不支持事務(wù)處理等高級(jí)處理,而InnoDB類型支持。MyISAM類型的表強(qiáng)調(diào)的是性能,其執(zhí)行數(shù)度比InnoDB類型更快,但是不提供事務(wù)支持,而InnoDB提供事務(wù)支持已經(jīng)外部鍵等高級(jí)數(shù)據(jù)庫(kù)功能。2008-04-04php獲取后臺(tái)Job管理的實(shí)現(xiàn)代碼
從數(shù)據(jù)庫(kù)中取出job 隊(duì)列 創(chuàng)建新的進(jìn)程進(jìn)行執(zhí)行 等待job 結(jié)束2011-06-06PHP中4個(gè)加速、緩存擴(kuò)展的區(qū)別和選用建議
這篇文章主要介紹了PHP中eAccelerator、memcached、xcache、APC等4個(gè)加速、緩存擴(kuò)展的區(qū)別和選用建議,需要的朋友可以參考下2014-03-03令PHP初學(xué)者頭疼十四條問(wèn)題大總結(jié)
今天為大家奉上令PHP初學(xué)者頭疼問(wèn)題大總結(jié),下面提出的14個(gè)問(wèn)題希望對(duì)PHP初學(xué)者有所幫助。2008-11-11PHP使用反向Ajax技術(shù)實(shí)現(xiàn)在線客服系統(tǒng)詳解
這篇文章主要介紹了PHP使用反向Ajax技術(shù)實(shí)現(xiàn)在線客服系統(tǒng),簡(jiǎn)單描述了反向ajax的概念、原理及使用反向ajax實(shí)現(xiàn)在線客服的相關(guān)操作技巧,需要的朋友可以參考下2019-07-07php中session_unset與session_destroy的區(qū)別分析
關(guān)于session_unset()和session_destroy()的函數(shù)使用進(jìn)行介紹。學(xué)習(xí)php的朋友可以參考下。2011-06-06