PHP-FPM 是怎么影响 PHP 连接数据库的速度的?
19


问题解决了!感谢大家的热情帮助。等我理清这几天纠结的问题再把原因和过程发出来。


最终解决问题是这样的:
根据阿里云的ecs性能指标,我最后看到了每次重启之后,内存占用率是很低的,但当访问了几次之后,内存开始飙高,同时速度也开始变慢。
这个和我的fpm配置有关,我的fmp子进程是静态分配的,于是每一次进程打开,始终占用着内存。
最近太忙,一拖拖了两个月,实在sorry。
file
就是这样,大致原因就是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 于 11个月前 加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 12

有没有大神帮忙看下?

11个月前
Summer

友情帮顶~

11个月前

@Summer 哇,感谢!这个问题已经困扰我很久,跪求大神们帮忙解决下!

11个月前

本人愚见: 有几个排查点希望能帮到你

  1. 一个php-fpm进程大概是占用内存大概在20-30M之间,所以 ps -ef | grep php-fpm | grep -v grep | wc -l
    然后用检测出来的数字乘以 20-30M之间的数字, 这样看看内存是否够用
  2. 用free -m 进一步判断内存的使用量
  3. 如果数据库和应用在同一台服务器上的话, 注意pdo链接的时候用localhost 地址 不要用 服务器的内网ip(我吃过这个亏)
  4. 最后一点就是如果上面的点都解决不了你的问题的话, 在你频繁链接mysql的时候用iostat看看系统io
11个月前

@KinyouXY 感谢兄弟。

我在排查过程中,有一直在查看fpm的进程数,基本就在我设置的那个数。

另外内存肯定是够用的,还有好多g是空的。

仍然非常感谢你!

11个月前

我猜很大概率是环境配置的问题...
我的一个无脑思路:

  1. 新开一台 ECS
  2. https://oneinstack.com/ 这个安装包装一个环境
  3. 同样的代码,同样的操作,在新环境确定一下有没有问题
    如果没问题的话,就对比一下配置~
    PS:不是给 oneinstack 打广告~
11个月前

RDS 四核8G 太有钱了。。。。

目测还是 php-fpm 配置问题,可以仔细研究一下。以及,PDO_MYSQL 只是三种 API(mysql, mysqli)的一种,底层驱动有两种:mysql, mysqlnd,可以试试调整底层驱动。从现象看,是 php-fpm 和 mysql 服务器保持 tcp 长连接的问题。

11个月前
leung0826

找到原因说一声哈

9个月前

之前遇到一个问题,哪怕只是渲染一个简单静态html页面,刷几百次之后服务器就会挂掉,找了很久也没找到原因;
然后就换了一台服务器了

9个月前

大佬 如何实现重载的?

9个月前

pm.max_requests 设置的多少?

不会是1吧。。。。。。。。。。。。。。。。。。。

9个月前

  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!