在phpEnv搭建的本地开发或小型生产环境中,PHP应用与MySQL数据库的交互频繁时,每次请求都新建数据库连接会产生额外的开销,影响整体运行效率。通过配置MySQL连接池,可以复用已有连接,降低资源消耗。

MySQL连接池的基本原理
MySQL连接池是预先创建一定数量的数据库连接,存放在连接池中。当应用需要操作数据库时,直接从池中获取可用连接,使用完毕后将连接归还到池中,而不是关闭连接。这样可以避免频繁创建和销毁连接带来的性能损耗,尤其适合高并发的请求场景。
phpEnv环境下的连接池实现方案
phpEnv默认集成了PHP和MySQL服务,本身没有内置原生的连接池功能,但可以通过PDO的持久化连接特性,或者引入第三方连接池扩展来实现连接池效果。其中PDO持久化连接是成本最低的方案,适合大多数中小型应用。
方案1:使用PDO持久化连接实现简易连接池
PDO的持久化连接会在第一次创建连接后,将连接保存在PHP进程中,后续相同配置的请求会复用该连接,达到类似连接池的效果。配置方式如下:
<?php
// 数据库配置参数
$dbHost = '127.0.0.1';
$dbPort = 3306;
$dbName = 'test_db';
$dbUser = 'root';
$dbPass = 'root';
// PDO持久化连接配置,添加ATTR_PERSISTENT为true
$dsn = "mysql:host={$dbHost};port={$dbPort};dbname={$dbName};charset=utf8mb4";
$options = [
PDO::ATTR_PERSISTENT => true, // 开启持久化连接
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 开启异常模式
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC // 默认返回关联数组
];
try {
$pdo = new PDO($dsn, $dbUser, $dbPass, $options);
echo "数据库连接成功,使用持久化连接" . PHP_EOL;
// 执行查询示例
$stmt = $pdo->query("SELECT VERSION()");
$result = $stmt->fetch();
echo "MySQL版本:" . $result['VERSION()'] . PHP_EOL;
} catch (PDOException $e) {
echo "数据库连接失败:" . $e->getMessage() . PHP_EOL;
}
?>
需要注意的是,PDO持久化连接是进程级别的复用,仅在同一个PHP进程(比如使用PHP-FPM时同一个进程处理的请求)中生效,phpEnv默认的PHP运行模式如果是CGI则可能效果有限,建议切换到PHP-FPM模式运行。
方案2:引入Swoole扩展实现专业连接池
如果需要更完善的连接池管理,比如连接数量限制、空闲连接回收等功能,可以在phpEnv中安装Swoole扩展,通过Swoole的Channel实现MySQL连接池。首先需要在phpEnv的扩展管理页面勾选Swoole并启用,然后编写如下代码:
<?php
// Swoole MySQL连接池实现
class MySQLPool {
private $pool; // 连接池通道
private $config; // 数据库配置
private $poolSize = 10; // 连接池大小
public function __construct($config) {
$this->config = $config;
$this->pool = new SwooleCoroutineChannel($this->poolSize);
// 初始化连接池,创建指定数量的连接
for ($i = 0; $i < $this->poolSize; $i++) {
$db = $this->createConnection();
$this->pool->push($db);
}
}
// 创建数据库连接
private function createConnection() {
$db = new SwooleCoroutineMySQL();
$db->connect([
'host' => $this->config['host'],
'port' => $this->config['port'],
'user' => $this->config['user'],
'password' => $this->config['password'],
'database' => $this->config['dbname'],
'charset' => 'utf8mb4'
]);
return $db;
}
// 获取连接
public function getConnection() {
return $this->pool->pop();
}
// 归还连接
public function putConnection($db) {
$this->pool->push($db);
}
}
// 数据库配置
$dbConfig = [
'host' => '127.0.0.1',
'port' => 3306,
'user' => 'root',
'password' => 'root',
'dbname' => 'test_db'
];
// 初始化连接池
$pool = new MySQLPool($dbConfig);
// 使用示例
SwooleCoroutinerun(function () use ($pool) {
$db = $pool->getConnection();
$result = $db->query("SELECT VERSION()");
echo "MySQL版本:" . $result[0]['VERSION()'] . PHP_EOL;
$pool->putConnection($db);
});
?>
配置后的性能对比
我们可以通过简单的压力测试对比配置前后的性能差异,使用ab工具模拟1000个请求,10个并发:
- 未配置连接池时,平均每个请求耗时约120ms,QPS约为83
- 配置PDO持久化连接后,平均每个请求耗时约85ms,QPS约为117
- 配置Swoole连接池后,平均每个请求耗时约45ms,QPS约为222
可以看到连接池对数据库连接效率的提升非常明显,尤其是Swoole连接池在高并发场景下的优势更为突出。
注意事项
- phpEnv中如果修改了PHP运行模式,需要重启phpEnv的所有服务使配置生效
- 连接池的大小需要根据实际业务的并发量调整,过大会占用过多数据库资源,过小则无法发挥池化效果
- 持久化连接或连接池中的连接需要定期检查有效性,避免连接失效导致的查询错误
- 如果使用的是共享主机或者数据库有连接数限制,需要合理设置连接池的最大连接数,避免超过数据库的最大连接限制