php实现mysql连接池效果实现代码
php实现mysql连接池效果实现代码_php技巧_脚本之家 https://www.jb51.net/article/133709.htm
循环从mysql连接池中获取连接,不需要重复创建新的连接。
参考配置修改:可以参考下面的文章
防止访问量过大,把连接数占满了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
<?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 ); } } //从数据库连接池中获取一个数据库链接资源 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>数据库连接池中已无链接资源,请稍后重试!</mark>" ); } } //将用完的数据库链接资源放回到数据库连接池 public function release( $conn ) { echo 'release' . count ( $this ->_pools) . "<br>" ; if ( count ( $this ->_pools) >= self::POOLSIZE) { throw new ErrorException ( "<mark>数据库连接池已满!</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 ; } } } |
在另外的文件这样调用
1
2
3
4
5
6
7
8
9
10
|
<?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的连接池使用方法
因为一个小bug,导致项目在某个晚上向mysql发送了大量的连接请求,同时mysql服务器的dns出现问题,导致反解超时。最后活活的把mysql服务器拖挂了。
最后bug修复了,并研究了一下增加 mysql连接池的办法。
这两天搜了一下,发现ThinkPHP文档里没有连接池的相关文档。所以自己研究了下代码。
首先: PHP常用的mysql扩展库有三种 : mysql, mysqli, pdo_mysql.
* mysqli 是不支持连接池的。
* pdo_mysql 支持,但是,thinkPHP的pdo扩展不支持mysql,仅支持:'MSSQL','ORACLE','Ibase','OCI' . ( 见 Pdo.class.php 的第59行)
* mysql 支持,通过方法:mysql_pconnect . (具体参数可以看php官方文档)
1 使ThinkPHP启用 长连接的方式是:
1
2
3
4
5
6
7
8
9
10
11
|
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), ); } |
如果你认为,配置这个就万事大吉了,那就大错特错了。
2 mysql -> my.cnf修改配置:
[mysqld]
interactive_timeout =60 // 交互连接(mysql-client)的过期时间。
wait_timeout =30 // 长连接的过期时间时间。 这个一定要改啊!默认是8个小时。 如果请求量大点,很快连接数就占满了。
max_connections = 100 //最大连接数,可以认为是连接池的大小
3 php.ini 修改:
[MySql]
mysql.allow_persistent = On
mysql.max_persistent = 99 // 要小于mysql配置的最大连接数
mysql.max_links = 99
4 webserver如果是apache ,需要启用keep-alive。 否则,一旦请求退出,长连接将无法再重用。
webserver 是nginx的情况:
pm = dynamic // 默认启动一些子进程,用于处理http请求。
pm.max_children // 最大的子进程数。 这个配置要小于 mysql 的max_connections。
5 如果发现还是不能用,请检查操作系统的keepalive 是否启用。
综述:
需要 keep-alive 和 数据库长连接同时启用,否则长连接回白白的占用mysql的连接数资源,而无法重用。
对于 nginx + php-fpm 的情况,其实是保持了 php-fpm 子进程与mysql的长连接。 前端的http请求被分配给哪个 php-fpm子进程,该子进程就重用自己与mysql 的长连接。
上述是一整天的研究结果,不完备的地方,请大家指出,在此先行谢过!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!