PHP-FPM 调优
一:CGI和FastCGI
1:CGI:一种基于浏览器的输入、在Web服务器上运行的程序方法。据说早期的web只能处理HTML静态文件,随着社会的发展,远远不能满足需要,比如用户如何交互?这时候出现了动态语言,比如PHP,那么PHP如何与web服务器通信,这就是CGI协议。
webserver收到请求,fork一个cgi进程,请求结束后在干掉cgi进程,就这样频繁的开启、干掉,据说很浪费资源,性能不好。有点类似于http一问一答的短链接
2:FastCGI:于是人们在CGI的基础上改进,又搞了个FastCGI协议。
Fastcgi先启一个master,解析配置文件,初始化执行环境,然后再启动多个worker。当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。这样就避免了重复的劳动,效率自然提高。而且当worker不够用时,master可以根据配置预先启动几个worker等着;当然空闲worker太多时,也会停掉一些,这样就提高了性能,也节约了资源。这就是fastcgi的对进程的管理。
二:FPM
是一个PHP的基于FastCGI的管理器。
PHP-FPM 进程管理器有两种进程组成,一个 Master 进程和多个 Worker 进程。Master 主要用来管理worker进程,它本身不处理请求。Worker 进程接收来自 Web 服务器的请求,worker 进程则一般有多个 (依据配置决定进程数),每个进程内部都嵌入了一个 PHP 解释器,用来执行 PHP 代码。
关于FPM和NGINX的配置,这里不做介绍。下面看下FPM常用的优化点
三:FPM优化
以ubuntu18 apt安装php7.2为例的配置文件为例,打开:/etc/php/7.2/fpm/pool.d/www.conf,配置是通用的,其他不同系统,版本,安装方法不同,配置文件路径不一样
1:FPM有 3 种运行方式,文档介绍了2种
static:静态
这种方式子进程数量是固定的,不会变,pm.max_children 设置多少就是多少,缺点是不太灵活,优点是不像动态配置那样因为管理进程频繁的fork,kill操作等带来的开销,如果内存不多,访问量不大,不建议用这个,反之如果机器内存较大,用这个最佳。
dynamic:动态
这种方式动态增加子进程,当请求大的时候,增加,空闲的时候减少,这里有一个最大和最小的配置,因为经常变动,所以有管理进程带来的额外开销,一般情况下,内存不大,访问量不高,建议设置这种。
ondemand:动态(按需)
有请求的时候才启动,这种没有研究过,据说没有流量时关闭空闲进程,然后最终会产生与流量波动很大一样的开销问题 (除非您设置空闲超时的时间非常非常的长)
pm = dynamic #默认为动态
我们看静态和动态这两种的主要配置:
动态:
pm = dynamic动态方式下限定php-fpm的最大进程数(这里要注意pm.max_spare_servers的值只能小于等于pm.max_children) pm.max_children:开启的php-fpm进程数量,最大不会超过这个数 pm.start_servers:动态方式下的起始php-fpm进程数量。 #默认值:min_spare_servers + (max_spare_servers - min_spare_servers) / 2 pm.min_spare_servers:动态方式空闲状态下的最小php-fpm进程数量。 pm.max_spare_servers:动态方式空闲状态下的最大php-fpm进程数量。
静态:
pm = static pm.max_children:开启的php-fpm进程数量注意:如果配置静态,那么pm.start_servers,pm.min_spare_servers,pm.max_spare_servers三个参数不起作用
2:合理配置
我们可以通过 status查看fpm状况,这种方式需要配置nginx和php的fpm配置,然后重启
nginx:
server { listen 80; server_name 127.0.0.1; location ~/status$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }把fpm配置的status打开,apt安装在:/etc/php/7.2/fpm/pool.d/www.conf,手动编译,假如编译到/usr/local/php目录,那么文件在这里:/usr/local/php/etc/php-fpm.d/www.conf,搜索status_path,去掉前面的分号。
pm.status_path = /status搞完后重启,运行curl查看:
# curl 127.0.0.1/status pool: www #php-fpm pool的名称,大多数情况下为www process manager: dynamic #上面介绍的3中进程管理方式 start time: 23/Dec/2020:15:07:21 +0800 #fpm最近一次启动时间 start since: 4006 #fpm最近一次启动时间到现在运行了多少秒 accepted conn: 19 #fpm最近一次启动到现在接受到的请求数 listen queue: 0 #处于等待状态中的连接数,如果不为0,需要增加php-fpm进程数 max listen queue: 0 #fpm启动到现在处于等待连接的最大数量 listen queue len: 128 #当前等待连接队列的套接字大小 idle processes: 1 #当前空闲状态的进程数 active processes: 1 #当前活动状态的进程数 total processes: 2 #进程总数 max active processes: 1 #fpm启动到现在最多有几个进程处于活动状态 max children reached: 0 #pm试图启动更多的children进程时,却达到了进程数的限制,达到一次记录一次,如果不为0,需要增加php-fpm pool进程的最大数 slow requests: 0 #当启用了php-fpm slow-log功能时,如果出现php-fpm慢请求这个计数器会增加,一般不当的Mysql查询会触发这个值
也可以用linux命令查看:
# ps aux | grep php-fp[m] | grep -v master | wc -l #查看进程数,去掉master进程和进程本身待续……