PHP-FPM调优
PHP的几种运行方式
PHP
本身是一个php代码的脚本执行程序,他有以下几种运行方式:
- 模块加载运行方式(
Apache
) - CGI运行方式 (
Apache
) - FastCGI运行方式 (几乎通用)
- ISAPI运行方式(Window下Apache)
- CLI运行方式(命令行)
前四种是提供给web服务器来处理php代码文件,其中模块加载的方式其实是最快的,但 FastCGI
配合 NGINX
的web服务是目前的主流。
从CGI到PHP-FPM
- CGI
Common Gateway Interface(公共网关接口)
简称 CGI
,每当客户请求 CGI
的时候,WEB
服务器就请求操作系统生成一个新的CGI
解释器进程,CGI
的一个进程则处理完一个请求后退出,下一个请求来时再创建新进程。这样在访问量少的情况也还能使用,可是当访问量增加,产生并发的情况下,这种方式就不适合了,于是就有了 FastCGI
- FastCGI
FastCGI
像是一个常驻型的CGI
,它可以一直执行着,只要激活后,不会每次都话费时间去fork
一次。
在启动FastCGI
的时候它就启动了多个CGI
解释器进程并等待 Web Server
的请求,结束完就又重新等待请求。
- PHP-FPM
PHP-FPM
就是FastCGI
的实现,并提供了进程管理的功能,进程包含master
进程和worker
进程两种,master
进程只有一个,负责监听端口,接收请求,而worker
进程则一般有多个(具体数量根据实际需要配置)。
每个进程内部都嵌入了一个PHP
解释器,是PHP
代码真正执行的地方。
多方面调优
php.ini配置
;这个是配置禁用危险函数
disable_functions=eval...
;上传文件大小限制
post_max_size =16M
upload_max_filesize= 16M
;脚本执行时间限制
max_execution_time= 60
max_input_time =60
;脚本内存限制,一般设为128M,如非必要(无可避免的上传大文件/处理大数组)不增加
memory_limit =128M
php-fpm配置
;错误日志处理
error_log =/var/log/php-fpm/error.log
log_level = notice
;异常自启(表示60s内出现 60次 SIGSEGV orSIGBUS 异常时候,自动重启)
emergency_restart_threshold= 60
emergency_restart_interval= 60s
;设置子进程接受主进程复用信号的超时时间
process_control_timeout= 0
;后台执行php-fpm
daemonize = yes
pool资源池配置
每个文件代表一个资源池,机器性能足够时,可以区分多个资源池,隔绝不同的php应用,默认是www.conf
;监听方式,用tcp方式较稳定
listen = 127.0.0.1:9000
;backlog,排队长度设置
listen.backlog = 4096
;慢处理日志,表示超过45秒则记录为慢处理
request_slowlog_timeout = 45s
slowlog = /var/log/php-fpm/www-slow.log
具体设置问题
- pm
pm
默认是dynamic
动态的,但是一般我们的生产环境都是设置静态static
- pm.max_children
最大子进程数量,越多越好,但是受限机器性能,因此需要根据机器来配置,一般每个php-cgi
耗费的内存为20M~40M
,如果最大数量设置为100,那么总共需要的内存就在2000M~4000M
,如果这个值设置的比较小,那么等待的请求时间会出现502超时,所以需要根据服务器运行的程序大小,计算出剩余内存,再计算子进程数。
- pm.max_requests
为了避免内存泄露,PHP-FPM
有这么一个机制,当一个php-cgi
进程处理的请求数达到这个配置后,则会重启该进程,所以在高并发的情况下,经常导致502错误,解决方法就是把这个值设置大一点,减少进程重启次数,一般设置1024
- pm.min_spare_servers
保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程,一般可以设置为10
- pm.max_spare_servers
保证空闲进程数最大值,如果空闲进程大于此值,则进行清理,一般可以设置为30
- request_terminate_timeout
单个请求的超时终止时间,超时后会终止进程,nginx
发现信号中断,就会给客户端返回502