首頁 後端開發 php教程 C实现PHP的MySQL数据库连接池

C实现PHP的MySQL数据库连接池

Jun 23, 2016 pm 01:17 PM

一、导语

连接池在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模式)

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

实现思路图:

图片:1.jpg

四、理解PHP线程与进程的工作模式

(一)多进程工作模式

PHP的多进程工作模式以Apache apxs举例。

apache启动时,会fork出N个子进程用来等待接受处理客户端的请求。进程之间相互隔离,全局变量也无法直接访问(可以通过进程间通信访问)。这样的好处是能够保证PHP环境的长时间稳定,

即使有部分进程因内存泄漏而崩溃也不会影响其他进程。由于PHP相当于粘合剂,它实际相当于集合多个库的API,例如集合了libcurl、libmemcache、libzip等,要保证所有的库都正常运行是比较困难的。

那么为了保证PHP的高可靠性,这种多进程的模式就是首选。

图片:2.jpg

(二)多线程工作模式

PHP的多线程工作模式以IIS举例。

这种模式下,只有一个进程在后台运行着,所有请求都是通过这一个进程来完成。只是在处理每个请求时,会创建独立的线程来处理。

正是因为使用多线程这种模式,可以直接访问全局变量得以方便的实现数据库连接池。

图片:3.jpg

六、使用此扩展前提条件与方法

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

七、相关下载

扩展dll下载: php_my_mysql.dll

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

扩展测试结果

测试配置:

[my_mysql]

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释放,就没有办法测试连接被占用的情况。
登入後複製

测试结果图:

图片:4.jpg

返回warning的,是由于连接池资源被占用完,会进入等待。如果1.5s仍没有等待到资源,则返回dbpool is exhushed。
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

會話如何劫持工作,如何在PHP中減輕它? 會話如何劫持工作,如何在PHP中減輕它? Apr 06, 2025 am 12:02 AM

會話劫持可以通過以下步驟實現:1.獲取會話ID,2.使用會話ID,3.保持會話活躍。在PHP中防範會話劫持的方法包括:1.使用session_regenerate_id()函數重新生成會話ID,2.通過數據庫存儲會話數據,3.確保所有會話數據通過HTTPS傳輸。

描述紮實的原則及其如何應用於PHP的開發。 描述紮實的原則及其如何應用於PHP的開發。 Apr 03, 2025 am 12:04 AM

SOLID原則在PHP開發中的應用包括:1.單一職責原則(SRP):每個類只負責一個功能。 2.開閉原則(OCP):通過擴展而非修改實現變化。 3.里氏替換原則(LSP):子類可替換基類而不影響程序正確性。 4.接口隔離原則(ISP):使用細粒度接口避免依賴不使用的方法。 5.依賴倒置原則(DIP):高低層次模塊都依賴於抽象,通過依賴注入實現。

在PHPStorm中如何進行CLI模式的調試? 在PHPStorm中如何進行CLI模式的調試? Apr 01, 2025 pm 02:57 PM

在PHPStorm中如何進行CLI模式的調試?在使用PHPStorm進行開發時,有時我們需要在命令行界面(CLI)模式下調試PHP�...

PHP 8.1中的枚舉(枚舉)是什麼? PHP 8.1中的枚舉(枚舉)是什麼? Apr 03, 2025 am 12:05 AM

PHP8.1中的枚舉功能通過定義命名常量增強了代碼的清晰度和類型安全性。 1)枚舉可以是整數、字符串或對象,提高了代碼可讀性和類型安全性。 2)枚舉基於類,支持面向對象特性,如遍歷和反射。 3)枚舉可用於比較和賦值,確保類型安全。 4)枚舉支持添加方法,實現複雜邏輯。 5)嚴格類型檢查和錯誤處理可避免常見錯誤。 6)枚舉減少魔法值,提升可維護性,但需注意性能優化。

如何在系統重啟後自動設置unixsocket的權限? 如何在系統重啟後自動設置unixsocket的權限? Mar 31, 2025 pm 11:54 PM

如何在系統重啟後自動設置unixsocket的權限每次系統重啟後,我們都需要執行以下命令來修改unixsocket的權限:sudo...

解釋PHP中的晚期靜態綁定(靜態::)。 解釋PHP中的晚期靜態綁定(靜態::)。 Apr 03, 2025 am 12:04 AM

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

See all articles