PHP-FPM 是怎么影响 PHP 连接数据库的速度的?
问题解决了!感谢大家的热情帮助。等我理清这几天纠结的问题再把原因和过程发出来。
最终解决问题是这样的:
根据阿里云的ecs性能指标,我最后看到了每次重启之后,内存占用率是很低的,但当访问了几次之后,内存开始飙高,同时速度也开始变慢。
这个和我的fpm配置有关,我的fmp子进程是静态分配的,于是每一次进程打开,始终占用着内存。
最近太忙,一拖拖了两个月,实在sorry。
就是这样,大致原因就是fpm子进程处理请求得到内存资源后,没有重载。我设置了每执行一次就重载,问题就解决了。
问题
PHP-FPM是怎么影响PHP连接数据库的速度的?
引发原因
PHP脚本连接Mysql耗时非常不稳定,最快10ms,最慢1s+。
环境
- linux是阿里云的ecs,4核/8G/4Mbps/华东1/centOs7
- Lnmp1.4集成环境包
- Mysql是阿里云RDS,4核/8G/Mysql5.6/华东1,与ecs内网连接
- PHP 版本 7.1.5,用PDO_MYSQL扩展,无Mysql扩展
脚本
<?php
// 取毫秒函数
function getMillisecond() {
list($t1, $t2) = explode(' ', microtime());
return (float)sprintf('%.0f',(floatval($t1)+floatval($t2))*1000);
}
// 开始时间
$a = getMillisecond();
$db = new pdo($dsn,$name,$password); // 连接数据库
$db = null; // 销毁
// 耗时
$b = getMillisecond() - $a;
echo '<br>'.$b.'ms';
exit;
尝试
1.排除法
借朋友香港ecs运行同一个脚本,快的时候没有我华东ecs快,但却一直稳定在30-60ms之间,最慢也只要200ms以下,始终稳定。
由此排除数据库和脚本问题,定位问题在服务器上面。
2.php.ini
香港ecs是php5.6,我的是php7.1.5,都用PDO,排除是连接驱动的问题
一一对比两个配置文件,只有一些版本差异,关键参数大致一样,连接驱动也都允许持久连接,排除是配置文件的问题
3.找规律
重启lnmp后,发现访问数据库的速度变快了,我在浏览器疯狂刷新,发现大概到了300左右时,就开始变慢,从原本的50ms以下,涨到700ms+
再次重启服务,反复尝试,的确都在刷新300次左右。
4.fpm
300这个数字,让我想起我的fpm配置,是静态分配子进程300个,即php-fpm有300个进程是长时间运行着的。我把它改成10,重启服务后,发现刷新10次,就开始变慢。
看来这就是规律所在了。
除此之外,我还发现另外一个规律。
当我刷新10次后,访问数据库变慢,但我按慢的速度再访问10次左右,速度又变快了,快了将近20次,然后又变慢,又10次,变快,又20次,变慢……再往后就时快时慢,很难找出规律了。
猜测可能是进程被释放了还是咋滴(但还有一点不明白,如果进程会根据时间释放,我也尝试过半小时候再来刷新,讲道理进程总该释放了吧?但还是慢的。只有重启lnmp服务,才会重新变快。)
5.对比
再接着,我虽然不明白原理,但马上去找了香港ecs的fpm配置,发现它对于子进程的配置是动态的,由于服务器配置不同,数字互相是不一样的,我就先按自己的服务器配置计算后分配。
pm = dynamic
pm.max_children = 450 // 允许最大进程数
pm.start_servers = 50 // 服务启动时预先就绪的进程数
pm.min_spare_servers = 5 // 最小空闲进程数
pm.max_spare_servers = 320 // 最大空闲进程数
讲道理,配置上文件和香港ecs已经一样了,重启服务后,却发现,依旧不是想要的结果。
快慢的节奏变成了刷一次快,再刷一次慢,然后这样反复(和香港ecs完全稳定的节奏不一样)。
到这,我已经没有思路了,我在想我可能还有忽略掉php和fpm之间的某种规则,或者是我的整个逻辑存在纰漏。但我实在不知道这个问题该怎么解决了。
跪求走过路过的大神们好心帮个忙,这个问题实在困扰我很久了。
有没有大神帮忙看下?
友情帮顶~
@Summer 哇,感谢!这个问题已经困扰我很久,跪求大神们帮忙解决下!
本人愚见: 有几个排查点希望能帮到你
然后用检测出来的数字乘以 20-30M之间的数字, 这样看看内存是否够用
@KinyouXY 感谢兄弟。
我在排查过程中,有一直在查看fpm的进程数,基本就在我设置的那个数。
另外内存肯定是够用的,还有好多g是空的。
仍然非常感谢你!
我猜很大概率是环境配置的问题...
我的一个无脑思路:
如果没问题的话,就对比一下配置~
PS:不是给 oneinstack 打广告~
RDS 四核8G 太有钱了。。。。
目测还是 php-fpm 配置问题,可以仔细研究一下。以及,PDO_MYSQL 只是三种 API(mysql, mysqli)的一种,底层驱动有两种:mysql, mysqlnd,可以试试调整底层驱动。从现象看,是 php-fpm 和 mysql 服务器保持 tcp 长连接的问题。
找到原因说一声哈
之前遇到一个问题,哪怕只是渲染一个简单静态html页面,刷几百次之后服务器就会挂掉,找了很久也没找到原因;
然后就换了一台服务器了
大佬 如何实现重载的?
pm.max_requests 设置的多少?
不会是1吧。。。。。。。。。。。。。。。。。。。