• 1
  • 2
  • 3
  • 4
  • 5
mysql数据库问题 首 页  »  帮助中心  »  数据库  »  mysql数据库问题
用C来实现PHP的MySQL数据库连接池
发布日期:2016-4-26 19:4:41

  一、导语

  连接池在JAVA中应用的很广泛,但是在PHP中很少使用。

  这里以Mysql为例,JAVA中使用连接池的原因之一是避免重复新建、释放连接资源带来的开销。而在PHP中都是直连,因为这部分开销对于C API来说性能上是没有问题的。

  那么既然PHP直连已经没有了性能问题,那么为什么还要多次一举开发mysql的数据库连接池扩展呢?因为根本的目的是在于理解PHP的TS(Tthread Safe线程安全)和NTS(Not Thread Safe非线程安全)运行模式,而并不是数据库连接池这个功能。

  二、原理

  连接池的基本思想就是在系统加载时,初始化默认数量的连接对象存储在内存中,当有客户端需要访问数据库时,要根据场景选择是分配、新建、等待、失败返回连接对象。使用完以后,连接将被重新放置回连接池中等待下一个请求的再分配,而不是释放内存。

  连接池中连接的建立、释放都由连接池自身来管理,同时可以通过设置初始化最小连接数、最大连接数、最大空闲时间等来配置连接池。

  注:在此扩展中,提供了最小连接数(min_connection)、最大连接数(max_connection)的设置

  三、实现思路

  1.定义全局数组变量dbpools

  dbpools中的元素类型为

  struct _mysql_node{ MYSQL *mysql; //连接资源句柄 int is_used; //标记是否被占用 int result_id; //记录my_mysql_query的查询结果集} mysql_node;

  2.通过获取配置文件中设置的min_connection初始化dbpools

  3.定义全局变量db_pools_length(目前拥有链接数)、db_pools_use_length(目前被使用的链接数),通过这两个值来确定分配资源的情景

  注:正因为使用全局变量实现连接池,通过修改全局变量的状态来选择资源连接,决定了该扩展必须运行在共享全局变量的ZTS(Zend Thread Safe)线程安全模式下。(例如IIS或Apache MPM Worker模式)

  如果希望支持多进程,可以通过进程间通信来设置全局变量,实现线程池。

  实现思路图如下所示:

  

  四、理解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 //默认最小连接数

  看到这里的配置,能看出来这个数据库连接池扩展没有实现多数据源的连接池。因为目的不在连接池本身,所以也没有特地去写多数据源的功能。

  3.修改php.ini,添加

  extension=php_my_mysql.dll

  4.重启apache server

  七、相关下载

  源码下载:http://yunpan.cn/QWmEN8PuuRVYN

  扩展dll下载:php_my_mysql.dll

  扩展测试结果

  测试配置:

  [my_mysql]

  my_mysql.max_connection = 2 //最大连接数

  my_mysql.min_connection = 1 //默认最小连接数

  使用三个浏览器,运行下列测试脚本:

  

  

  测试结果图如下所示:

  

  返回warning的,是由于连接池资源被占用完,会进入等待。如果1.5s仍然没有等待到资源,那么返回dbpool is exhushed。