模式连接C实现PHP的mysql数据库连接池
每日一贴,今天的内容关键字为模式连接
一、导语
连接池在JAVA中应用的很普遍,而在PHP中很少应用。以Mysql为例,JAVA中应用连接池的原因之一是免避重复新建、释放连接源资带来的开销。而在PHP中都是直连,因为这部份开销对于C API而言性能上是没有题问的。
那么既然PHP直连经已没有性能题问,那为何还要多次一举开辟mysql的数据库连接池扩展呢?因为本根的的目是在于懂得PHP的TS(Tthread Safe程线全安)与NTS(Not Thread Safe非程线全安)运行模式,而并非数据库连接池这个功能。
二、理原
连接池的基本思想是在系统加载时,初始化认默数量的连接对象存储在内存中,当有客户端须要问访数据库时,根据场景选择是配分、新建、待等、失败返回连接对象。应用终了后之,连接将被从新放置回连接池中待等下一个请求的再配分,而不是释放内存。
连接池中连接的立建、释放都由连接池自身来管理,同时可以通过设置初始化最小连接数、最大连接数、最大闲暇时光等来配置连接池。
注:在此扩展中,供给了最小连接数(min_connection)、最大连接数(max_connection)的设置
三、实现思绪
1.义定全局组数量变dbpools
dbpools中的素元类型为
2.通过获得配置文件中设置的min_connection初始化dbpools
3.义定全局量变db_pools_length(现在有拥链接数)、db_pools_use_length(现在被应用的链接数),通过这两个值来肯定配分源资的景情
注:正因为应用全局量变实现连接池,通过改修全局量变的态状来选择源资连接,定决了该扩展必须运行在享共全局量变的ZTS(Zend Thread Safe)程线全安模式下。(例如IIS或Apache MPM Worker模式)
如果希望支撑多程进,可以通过程进间通信来设置全局量变,实现程线池。
dbpools中的素元类型为
struct _mysql_node{ MYSQL *mysql;//连接源资柄句 int is_used;//标记否是被占用 int result_id;//记载my_mysql_query的询查结果集 } mysql_node;
3.义定全局量变db_pools_length(现在有拥链接数)、db_pools_use_length(现在被应用的链接数),通过这两个值来肯定配分源资的景情
注:正因为应用全局量变实现连接池,通过改修全局量变的态状来选择源资连接,定决了该扩展必须运行在享共全局量变的ZTS(Zend Thread Safe)程线全安模式下。(例如IIS或Apache MPM Worker模式)
如果希望支撑多程进,可以通过程进间通信来设置全局量变,实现程线池。
实现思绪图:
![](http://img-my.csdn.net/uploads/201304/22/1366626299_2281.png)
四、懂得PHP程线与程进的作工模式
(一)多程进作工模式
PHP的多程进作工模式以Apache
apxs举例。
apache启动时,会fork出N个子程进用来待等接受理处客户端的请求。程进之间互相离隔,全局量变也没法直接问访(可以通过程进间通信问访)。这样的利益是够能保障PHP环境的长时光定稳,
即使有部份程进因内存泄漏而崩溃也不会影响其他程进。由于PHP相当于粘合剂,它现实相当于合集多个库的API,例如合集了libcurl、libmemcache、libzip等,要保障有所的库都正常运行是较比难题的。
那么为了保障PHP的高可靠性,
这类多程进的模式就是首选。
(二)多程线作工模式
PHP的多程线作工模式以IIS
举例。
这类模式下,只有一个程进在后台运行着,有所请求都是通过这一个程进来实现。只是在理处个每请求时,会建创独立的程线来理处。
是正因为应用多程线这类模式,可以直接问访全局量变得以便利的实现数据库连接池。
六、应用此扩展前提条件与法方
1.widnwos下IIS Server或Apache多程线模式,php5.3.*
2.改修php.ini,添加
[my_mysql]
my_mysql.host = localhost
my_mysql.user = root
my_mysql.password =
my_mysql.port = 3306
my_mysql.max_connection = 200 //最大连接数
my_mysql.min_connection = 100 //认默最小连接数
my_mysql.host = localhost
my_mysql.user = root
my_mysql.password =
my_mysql.port = 3306
my_mysql.max_connection = 200 //最大连接数
my_mysql.min_connection = 100 //认默最小连接数
看到这里的配置,能看出来这个数据库连接池扩展没有实现多数据源的连接池。因为的目不在连接池本身,所以也没有特地去写多数据源的功能。
3.改修php.ini,添加
extension=php_my_mysql.dll
4.启重apache server
七、关相下载
扩展dll下载:
php_my_mysql.dll
扩展测试结果
测试配置:
[my_mysql]
my_mysql.max_connection = 2 //最大连接数
my_mysql.min_connection = 1 //认默最小连接数
my_mysql.max_connection = 2 //最大连接数
my_mysql.min_connection = 1 //认默最小连接数
应用三个浏览器,运行下列测试脚本:
<?php /** * 从数据库连接池中取得一个链接源资 * 可能产生如下景情 * 1.如果有闲暇连接则直接返回链接源资 * 2.如果没有闲暇连接,并且连接数没有超过最大连接数,则扩充连接池并返回新建的链接源资 * 3.如果没有闲暇连接同时经已是最大连接数,则进入待等,超过1.5s仍没有闲暇源资则超时返回NULL. * * 失败返回NULL */ $db = my_mysql_get_conn(); if($db === false){ exit('dbpool is exhushed.'); } /** * 选择数据库 * @param resource $db * @param string $db_name 数据库名称 */ my_mysql_select_db($db, 'test'); /** * ping数据库 */ my_mysql_ping($db); /** * 执行SQL语句,可以执行INSERT、SHOW、SELECT、UPDATE、DELETE等语句 * @param resource $db * @param string $sql SQL */ my_mysql_query($db, "INSERT INTO test VALUES(id, 'dbpool', 'test dbpool')"); // //获得上一条INSERT语句返回的自增ID $id = my_mysql_get_insert_id($db); echo $id; $result = my_mysql_query($db, "SELECT * FROM test"); /** * 将询查结果转换为二维组数 * @param resource $db */ $arr = my_mysql_fetch_assoc($result); print_r($arr); sleep(3); var_dump($db);//sleep后之,必须输出$db,否则会因为PHP的解析优化,sleep过程中经已将$db释放,就没有办法测试连接被占用的情况。
测试结果图:
![](http://img-my.csdn.net/uploads/201304/22/1366626221_4296.png)
返回warning的,是由于连接池源资被占用完,会进入待等。如果1.5s仍没有待等到源资,则返回dbpool is exhushed。
文章结束给大家分享下程序员的一些笑话语录:
女人篇
有的女人就是Windows虽然很优秀,但是安全隐患太大。
有的女人就是MFC她条件很好,然而不是谁都能玩的起。
有的女人就是C#长的很漂亮,但是家务活不行。
有的女人就是C++,她会默默的为你做很多的事情。
有的女人就是汇编虽然很麻烦,但是有的时候还得求它。
有的女人就是SQL,她会为你的发展带来莫大的帮助。