1、FPM是什么?
FPM(FastCGI 进程管理器)是 PHP FastCGI 的主要实现,实现了许多对高负载网站有用的功能。FPM 管理多个 PHP 进程,并通过 FastCGI 协议与 Web 服务器通信,提供更好的性能和资源管理。一般 nginx 服务器使用FPM。
PHP-FPM使用了多进程模型来处理PHP请求。当Web服务器接收到一个PHP请求时,它将该请求转发给PHP-FPM进程管理器。PHP-FPM会根据配置文件中的参数来创建、管理和回收PHP解释器进程(也称为worker进程),并将请求分配给这些worker进程来处理。这种多进程模型使得PHP-FPM能够处理大量并发请求,并提高PHP应用程序的性能和稳定性。
2、FPM的工作流程:
- Web服务器接收到一个包含PHP请求的HTTP请求。
- Web服务器将该请求转发给PHP-FPM进程管理器。
- PHP-FPM进程管理器接收到请求后,从空闲进程池中选择一个worker进程来处理该请求。如果没有空闲进程,则根据配置文件中的参数决定是否要创建新的worker进程。
- 选定的worker进程接收到请求后,会解析PHP代码并执行相应的操作。它可以连接数据库、进行文件读写、生成HTML等。
- worker进程将处理结果返回给PHP-FPM进程管理器。
- PHP-FPM进程管理器将处理结果返回给Web服务器。
- Web服务器将最终结果返回给客户端。
在整个工作流程中,PHP-FPM进程管理器负责管理worker进程的生命周期。它会监控进程的状态,并根据需要创建或回收worker进程,以确保有足够的进程来处理请求并避免资源浪费。
此外,PHP-FPM还提供了一些额外的功能,如进程池分配、连接池管理、动态进程调整等,以优化PHP应用程序的性能和可靠性。
3、进程管理相关配置
pm
string
设置进程管理器如何管理子进程。可用值:static
,ondemand
,dynamic
。必须设置。
static
- 子进程的数量是固定的(pm.max_children
)。
ondemand
- 进程在有需求时才产生(当请求时才启动。与 dynamic 相反,在服务启动时 pm.start_servers
就启动了。
dynamic
- 子进程的数量在下面配置的基础上动态设置:pm.max_children
,pm.start_servers
,pm.min_spare_servers
,pm.max_spare_servers
。
pm.max_children
int
pm
设置为 static
时表示创建的子进程的数量,pm
设置为 dynamic
时表示最大可创建的子进程的数量。必须设置。
该选项设置可以同时提供服务的请求数限制。类似 Apache 的 mpm_prefork 中 MaxClients 的设置和 普通PHP FastCGI中的 PHP_FCGI_CHILDREN 环境变量。
pm.start_servers
in
设置启动时创建的子进程数目。仅在 pm
设置为 dynamic
时使用。默认值:min_spare_servers + (max_spare_servers - min_spare_servers) / 2。
pm.min_spare_servers
int
设置空闲服务进程的最低数目。仅在 pm
设置为 dynamic
时使用。必须设置。
pm.max_spare_servers
int
设置空闲服务进程的最大数目。仅在 pm
设置为 dynamic
时使用。必须设置。
pm.max_spawn_rate
int
同时生成子进程的速率。仅当 pm
设置为 dynamic
时使用。默认值: 32
pm.process_idle_timeout
mixed
秒数,多久之后结束空闲进程。 仅当设置 pm
为 ondemand
。 可用单位:s(秒),m(分),h(小时)或者 d(天)。默认单位:10s。
pm.max_requests
int
设置每个子进程重生之前服务的请求数。对于可能存在内存泄漏的第三方模块来说是非常有用的。如果设置为 '0' 则一直接受请求,等同于 PHP_FCGI_MAX_REQUESTS 环境变量。默认值:0。
pm.status_listen
string
接受 FastCGI 状态请求的地址。会创建一个新不可见池用来独立处理请求。如果主池处理长时间运行的请求时很繁忙, 那么对长时间运行的请求结束之前能够获得 FPM 状态页面会非常有用。语法与 listen 指令相同。默认值:none。
pm.status_path
string
查看 FPM 状态页面的 URI。此值必须以斜线(/)开头。如果没有设置,则无法访问状态页面,默认值:无。
4、合理配置 PHP-FPM 进程管理
4.1、了解 PHP-FPM 的进程管理模式
- static:适合内存充足且请求量相对稳定的环境,可以避免频繁创建和销毁子进程带来的开销。
- dynamic:适合请求量波动较大的环境,可以根据负载动态调整子进程数量。
- ondemand:适合低流量网站,只有在请求到达时才启动子进程。
4.2、关注重要的配置选项
-
pm.max_children
:这个值应该根据服务器的 RAM 和单个 PHP 进程的平均内存使用量来设置。一个常见的公式是:pm.max_children = (总内存 - 保留内存) / 单个 PHP 进程的平均内存使用量
其中“保留内存”是给操作系统和其他服务预留的内存。
-
pm.start_servers
、pm.min_spare_servers
和pm.max_spare_servers
:在 dynamic 模式下,这些值应该设置在合理的范围内,从而在服务器负载变化时能够快速响应。通常,可以将pm.start_servers
设置为pm.max_children
的约 25%,然后将pm.min_spare_servers
和pm.max_spare_servers
分别设置为pm.start_servers
的约 50% 和 200%。 -
pm.max_requests
:这个值设定了处理多少请求后子进程会重启,可以防止长期运行的进程出现内存泄漏。如果您的应用很稳定,可以设置得更高一些;如果不确定或怀疑有内存泄漏问题,可以设置得比较低。 -
pm.process_idle_timeout
:在 dynamic 模式下,设置空闲进程在被回收之前应保持空闲状态的时间。合理的值可以是几十秒到几分钟。
4.3、监控与调整
-
监控:使用
top
、htop
、free
等命令或者更高级的监控工具(如 New Relic, Datadog)来监控内存和 CPU 使用情况。同时,注意 PHP-FPM 的日志文件,查看是否有错误或警告信息需要处理。 -
调整:如果发现服务器资源利用率不高,可以尝试增加
pm.max_children
。如果服务器资源紧张,考虑减少pm.max_children
或优化代码以减少每个请求所需的资源。 -
测试:在做出改变后,执行压力测试,观察更改是否有积极的影响,并继续进行微调。
4.4、例子
假设你有一个具有 8GB RAM 的服务器,每个 PHP 进程平均使用 50MB 内存,那么你可以这样配置(保留 2GB 内存给系统和其他服务):
pm.max_children = (8000MB - 2000MB) / 50MB = 120
pm.start_servers = 30
pm.min_spare_servers = 15
pm.max_spare_servers = 60
pm.max_requests = 1000
上述配置只是一个示例,实际情况下,您需要根据服务器的具体情况和您的应用特点去进行调整。记得,任何时候,更改配置后都要进行测试来确保新的配置可以正常工作并提供良好的性能表现。