Skip to main content

[转] PHP-FPM 配置与调优

原文地址 https://www.cnblogs.com/jiqing9006/p/10971865.html

PHP-FPM 是啥?

PHP-FPM 是一个 PHP FastCGI 的管理器,它实际上就是 PHP 源代码的补丁,旨在将 FastCGI 进程管理引进到 PHP 软件包中。

CGI 是啥?

CGI 全称 “公共网关接口”(Common Gateway Interface),是 HTTP 服务器与其它机器上的程序进行通信的接口,其程序须运行在网络服务器上。
CGI 可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。

FastCGI 是啥?优缺点。

FastCGI 是一个常驻型的 CGI,它可以一直执行,只要激活后,不会每次都要花费时间去 fork 一次(这是 CGI 最为人诟病的 fork-and-execute 模式)。它还支持分布式的运算,即 FastCGI 程序可以在网站服务器以外的主机上执行并且接受来自其它网站服务器来的请求。
FastCGI 是语言无关的、可伸缩架构的 CGI 开放扩展,其主要行为是将 CGI 解释器进程保持在内存中并因此获得较高的性能。我们知道,CGI 解释器的反复加载是 CGI 性能低下的主要原因,如果 CGI 解释器保存在内存中并接受 FastCGI 进程管理器调度,那么就可以提供良好的性能、伸缩性等。
因为是多进程,所以比 CGI 多线程消耗更多的服务器内存,PHP-CGI 解释器每进程消耗 7 至 25 兆内存,将这个数字乘以 50 或 100 就是很大的内存数。

FastCGI 工作原理(配置数量与内存大小关联)

Web 服务器启动时,载入 FastCGI 进程管理器。
FastCGI 进程管理器初始化,启动多个 CGI 解释器进程 (PHP-CGI) 并等待来自 Web 服务器的连接。
当客户端请求到达 Web 服务器时,FastCGI 进程管理器选择并连接到一个 CGI 解释器,Web 服务器将 CGI 环境变量和标准输入发送到 FastCGI 子进程 PHP-CGI。
FastCGI 子进程完成处理后将标准输出和错误信息从同一连接返回给 Web 服务器。当 FastCGI 子进程关闭连接时,请求便告处理完成。FastCGI 子进程接着等待并处理来自 FastCGI 进程管理器 (运行在 Web 服务器中) 的下一个连接。而在 CGI 模式中,PHP-CGI 在此便退出了。
在上述情况中,可以想象 CGI 通常有多慢,每一个 Web 请求 PHP 都必须重新解析 php.ini、重新载入全部扩展,并重初始化全部数据结构。而使用 FastCGI,所有这些都只在进程启动时发生一次。另外,数据库持久连接可以工作。

NOTE:FastCGI 的主要优点是把动态语言和 HTTP Server 分离开来,所以 Nginx 与 PHP/PHP-FPM 经常被部署在不同的服务器上,以分担前端 Nginx 服务器的压力,使 Nginx 专一处理静态请求和转发动态请求,而 PHP/PHP-FPM 服务器专一解析 PHP 动态请求。

PHP-CGI

PHP-CGI 是 PHP 自带的 FastCGI 管理器。
php-cgi 变更 php.ini 配置后需重启 php-cgi 才能让新的 php-ini 生效,不可以平滑重启。
直接杀死 php-cgi 进程,php 就不能运行了 (PHP-FPM 和 Spawn-FCGI 就没有这个问题,守护进程会平滑重新生成新的子进程)。

Nginx+PHP 配置

1、进程数优化

cd /usr/local/php/etc
# ll
-rw-r--r-- 1 root root 1228 5月 27 14:07 pear.conf
-rw-r--r-- 1 root root 480 5月 27 14:19 php-fpm.conf
-rw-r--r-- 1 root root 23046 5月 27 14:07 php-fpm.conf.default
-rw-r--r-- 1 root root 73862 6月 3 18:14 php.ini

修改 php-fpm.conf

pm = dynamic # 动态分配,如果pm设置为static,那么其实只有pm.max_children这个参数生效
pm.max_children = 200 # 静态方式下开启的php-fpm进程数量,在动态方式下他限定php-fpm的最大进程数
pm.start_servers = 120 # 动态方式下的起始php-fpm进程数量
pm.min_spare_servers = 5 # 动态方式空闲状态下的最小php-fpm进程数量
pm.max_spare_servers = 180 # 动态方式空闲状态下的最大php-fpm进程数量

NOTE:如果 pm 设置为 dynamic,4 个参数都生效。系统会在 php-fpm 运行开始时启动 pm.start_servers 个 php-fpm 进程,然后根据系统的需求动态在 pm.min_spare_servers 和 pm.max_spare_servers 之间调整 php-fpm 进程数。

2、最大请求数优化

pm.max_requests = 10240

NOTE:这个用来处理因为 PHP 解析器或引用的第三方库时,造成的内存泄露问题。
最大请求数:指一个 php-fpm 的工作进程在处理多少个请求后就终止掉。

3、最长执行时间优化 (php.ini)

request_terminate_timeout = 100

NOTE:
php 脚本取 max_execution_time 与 request_terminate_timeout 最小值作为脚本的超时时间。
这个是用来处理因为 PHP 执行时间超长而报 502 错误的解决。
这个时长配置可以在 php.ini(max_execution_time)或 php-fpm.conf 中配置均可,为了不影响全局配置,可在 php-fpm.conf 中实现。
需要结合 nginx.conf 配置。

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;

4、慢日志

request_slowlog_timeout = 2
slowlog = /home/wwwlogs/php_fpm_slow.log

NOTE:
开启慢日志的目的是为了跟踪分析那条 php 脚本执行的时间超过了设置的 request_slowlog_timeout 时长,如果超过这个设置时间,那么该脚本就会被记录下。

5、关闭重启

kill -INT `cat /usr/local/php/var/run/php-fpm.pid`
kill -USR2 `cat /usr/local/php/var/run/php-fpm.pid`

6、查看进程数

# ps aux | grep -c php-fpm

# ps aux | grep php-fpm | wc -l