数据库连接池耗尽参数优化外贸站点
外贸站点流量波动大,尤其是促销活动或海外客户集中访问时,可能突然出现“Too many connections”错误,页面加载缓慢甚至白屏。
这通常是数据库连接池耗尽导致的。
本文站在运维实操角度,教你从三个层面逐步优化,彻底解决这个问题。
前置准备
开始操作前,请确认以下几点:
- 拥有服务器的 SSH 登录权限(root 或 sudo 用户)。
- 知道网站运行环境(LNMP、LAMP 或宝塔面板等)。如果你的服务器用了宝塔,很多参数可以直接在后台修改。
- 备份当前配置文件(my.cnf、php-fpm.conf、项目中的 database.php 等),方便回滚。
检查数据库连接现状
登录服务器,先查看 MySQL 当前最大连接数和已用连接数:
mysql -u root -p -e "SHOW VARIABLES LIKE 'max_connections';"
mysql -u root -p -e "SHOW STATUS LIKE 'Threads_connected';"
如果 Threads_connected 接近或等于 max_connections,说明连接池已耗尽。
同时可以查看 Aborted_connects 和 Connection_errors_internal 辅助判断。
调整 MySQL 最大并发数
找到 MySQL 配置文件(通常为 /etc/my.cnf 或 /etc/mysql/my.cnf),在 [mysqld] 段增加或修改:
[mysqld]
max_connections = 500
注意:数值并非越大越好,建议根据服务器内存计算:每连接约占用 2~4MB(视查询复杂度),总内存的 20%~30% 用于连接池。例如 8GB 内存服务器可设为 500~800。
保存后重启 MySQL:
systemctl restart mysqld # 或 service mysql restart
优化 PHP-FPM 进程数
外贸站点通常使用 PHP 动态语言,PHP-FPM 进程数和数据库连接数直接相关。
编辑 PHP-FPM 配置文件(常见路径 /etc/php-fpm.d/www.conf 或宝塔面板的“PHP 管理”-“配置修改”):
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_children建议按每个 PHP 进程占用 30~50MB 计算,总内存的 60% 分配给 PHP。- 如果站点并发很高,可尝试
pm = static并固定pm.max_children,避免动态调整带来的波动。
修改后重启 PHP-FPM:
systemctl restart php-fpm
修改应用层连接池参数
许多外贸站点使用 ThinkPHP、Laravel 等框架,它们默认使用短连接(每次请求新建数据库连接)。
若要减少连接占用,可配置持久连接或调整连接池大小。
以 Laravel 为例,编辑 config/database.php:
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'options' => [
PDO::ATTR_PERSISTENT => true, // 启用持久连接
],
],
],
ThinkPHP 则可在 database.php 中增加 'persist' => true。
注意:使用持久连接时,PHP-FPM 进程会长期占用 MySQL 连接,需确保 max_connections 大于 pm.max_children。
避坑与验证
避坑提醒:
- 不要盲目提高
max_connections和pm.max_children,过大会导致内存耗尽(OOM)。 - 修改 MySQL 连接数后,建议同时增大
open_files_limit和table_open_cache。 - 如果使用持久连接,务必监控连接泄漏,某些框架在异常退出时不会释放连接。
效果验证:
- 重启所有服务后,用压力测试工具(如
ab或siege)模拟并发请求:
ab -n 1000 -c 100 http://你的外贸站点/
- 同时监控 MySQL 连接状态:
mysql -u root -p -e "SHOW STATUS LIKE 'Threads_connected';"
- 检查网站错误日志(
/var/log/php-fpm/或syslog)确认没有连接超时记录。
常见问题解答
Q:修改后 MySQL 无法启动?
A:可能是 max_connections 设置过高,或 open_files_limit 不足。先恢复配置文件,逐步增大。
Q:PHP-FPM 进程数调高后内存不够?
A:计算每个 PHP 进程的内存占用量(ps aux | grep php-fpm 看 RSS 列),然后按内存上限下调 pm.max_children。
Q:持久连接开启后连接数还是很高?
A:检查是否所有 PHP 进程都启用了持久连接,并且确认 MySQL 的 wait_timeout 设置足够长(默认 28800 秒无需修改)。
按照本文步骤依次操作,你的外贸站点数据库连接池耗尽问题基本能解决。
如果环境特殊,还可以微调 thread_cache_size、innodb_buffer_pool_size 等参数。
建议先测试再上线,确保稳定运行。