php-fpm配置

本文详细介绍了php-fpm的配置与优化,包括进程管理、动态与静态模式的选择、关键参数解析,以及如何开启php-fpm状态页进行监控。通过实例展示了如何根据服务器资源调整配置,以达到节省内存并提升系统稳定性的目的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

php-fpm是 FastCGI 的实现,并提供了进程管理的功能。进程包含 master 进程和 worker 进程两种进程。master 进程只有一个,负责监听端口,接收来自 Web Server 的请求,而 worker 进程则一般有多个(具体数量根据实际需要配置),每个进程内部都嵌入了一个 PHP 解释器,是 PHP 代码真正执行的地方。

那么php-fpm启动多少个进程,进程数是不是越多越好?这就需要按照业务的实际情况去配置了。

以我自己的环境为例php-fpm的配置文件有两个,分别是PHP安装目录下的 /etc/php-fpm.conf 和 /etc/php-fpm.d/www.conf

php-fpm.conf 的主要配置项:

pid = run/php-fpm.pid  #pid设置。

error_log = log/php-fpm.log  #错误日志。

log_level = notice  #错误级别。上面的php-fpm.log纪录的错误等级。可用级别为:alert(必须立即处理),error(错误情况),warning(警告情况),notice(一般重要信息),debug(调试信息)。 默认:notice、

emergency_restart_threshold = 0

emergency_restart_interval = 0  #表示在emergency_restart_interval所设值内出现SIGSEGV或者SIGBUS错误的php-cgi进程数如果超过 emergency_restart_threshold个,php-fpm就会优雅重启。这两个选项一般保持默认值。0 表示 '关闭该功能'。默认值: 0 (关闭)。

process_control_timeout = 0  #设置子进程接受主进程复用信号的超时时间。可用单位:s(秒),m(分),h(小时),或者 d(天) 默认单位: s(秒)。默认值: 0。

daemonize = yes  #作为守护进程运行php-fom。默认值为yes。

 www.conf 的主要配置项:

user = www

group = www  #启动进程的用户和用户组,FPM 进程运行的Unix用户,必须要设置。用户组,如果没有设置,则默认用户的组被使用。

listen = 127.0.0.1:9002  #fpm监听端口,即nginx中php处理的地址,一般默认值即可。可用格式为:'ip:port','port','/path/to/unix/socket'。每个进程池都需要设置。如果nginx和php在不同的机器上,分布式处理,就设置ip这里就可以了。

listen.owner = www

listen.group = www

listen.mode = 0666  #unix socket设置选项,如果使用tcp方式访问,这里注释即可。

listen.allowed_clients = 127.0.0.1  #允许访问FastCGI进程的IP白名单,设置any为不限制IP,如果要设置其他主机的nginx也能访问这台FPM进程,listen处要设置成本地可被访问的IP。每个地址是用逗号分隔。如果没有设置或者为空,则允许任何服务器请求连接。

pm = dynamic    #php-fpm进程启动模式,pm可以设置为static和dynamic和ondemand。

pm.max_children = 5    #子进程最大数。

pm.start_servers = 2    #启动时的进程数,默认值为:min_spare_servers + (max_spare_servers - min_spare_servers) / 2。

pm.min_spare_servers = 1    #保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程。

pm.max_spare_servers = 3    #保证空闲进程数最大值,如果空闲进程大于此值,则进行清理。

pm.max_requests = 500    #设置每个子进程重生之前服务的请求数。对于可能存在内存泄漏的第三方模块来说是非常有用的。

pm.status_path = /status    #fpm状态页面的网址。如果没有设置,则无法访问状态页面。

access.log = log/$pool.access.log    #每一个请求的访问日志,默认是关闭的。

access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"    #设定访问日志的格式。

slowlog = log/$pool.log.slow    #慢请求的记录日志,配合request_slowlog_timeout使用,默认关闭。

request_slowlog_timeout = 10s    #当一个请求该设置的超时时间后,就会将对应的PHP调用堆栈信息完整写入到慢日志中. 设置为 '0' 表示 'Off'。

request_terminate_timeout = 0    #设置单个请求的超时中止时间. 该选项可能会对php.ini设置中的'max_execution_time'因为某些特殊原因没有中止运行的脚本有用。

php-fpm配置优化

这部分内容转豆瓣https://www.douban.com/note/315222037/

背景
最近将Wordpress迁移至阿里云。由于自己的服务器是云服务器,硬盘和内存都比较小,所以内存经常不够使,通过Linux命令查看后,发现启动php-fpm进程数有20多个,占用了将近1G的内存,整个服务器才1.5G的内存,最后通过对php-fpm进程数优化解决了此问题,服务器多节省出600M的内存,将php-fpm的优化方法和大家分享下。
备注:目前根据nginx、fpm-php进行了内存优化,详情见相关资料
php-fpm优化

1、php-fpm优化参数介绍
他们分别是:pm、pm.max_children、pm.start_servers、pm.min_spare_servers、pm.max_spare_servers。

pm:表示使用那种方式,有两个值可以选择,就是static(静态)或者dynamic(动态)。
在更老一些的版本中,dynamic被称作apache-like。这个要注意看配置文件的说明。


下面4个参数的意思分别为:

pm.max_children:静态方式下开启的php-fpm进程数量
pm.start_servers:动态方式下的起始php-fpm进程数量
pm.min_spare_servers:动态方式下的最小php-fpm进程数
pm.max_spare_servers:动态方式下的最大php-fpm进程数量

区别:

如果dm设置为 static,那么其实只有pm.max_children这个参数生效。系统会开启设置数量的php-fpm进程。
如果dm设置为 dynamic,那么pm.max_children参数失效,后面3个参数生效。
系统会在php-fpm运行开始 的时候启动pm.start_servers个php-fpm进程,
然后根据系统的需求动态在pm.min_spare_servers和pm.max_spare_servers之间调整php-fpm进程数


2、服务器具体配置
对于我们的服务器,选择哪种执行方式比较好呢?事实上,跟Apache一样,运行的PHP程序在执行完成后,或多或少会有内存泄露的问题。
这也是为什么开始的时候一个php-fpm进程只占用3M左右内存,运行一段时间后就会上升到20-30M的原因了。
对于内存大的服务器(比如8G以上)来说,指定静态的max_children实际上更为妥当,因为这样不需要进行额外的进程数目控制,会提高效率。
因为频繁开关php-fpm进程也会有时滞,所以内存够大的情况下开静态效果会更好。数量也可以根据 内存/30M 得到,比如8GB内存可以设置为100,
那么php-fpm耗费的内存就能控制在 2G-3G的样子。如果内存稍微小点,比如1G,那么指定静态的进程数量更加有利于服务器的稳定。
这样可以保证php-fpm只获取够用的内存,将不多的内存分配给其他应用去使用,会使系统的运行更加畅通。
对于小内存的服务器来说,比如256M内存的VPS,即使按照一个20M的内存量来算,10个php-cgi进程就将耗掉200M内存,那系统的崩溃就应该很正常了。
因此应该尽量地控制php-fpm进程的数量,大体明确其他应用占用的内存后,给它指定一个静态的小数量,会让系统更加平稳一些。或者使用动态方式,
因为动态方式会结束掉多余的进程,可以回收释放一些内存,所以推荐在内存较少的服务器或VPS上使用。具体最大数量根据 内存/20M 得到。
比如说512M的VPS,建议pm.max_spare_servers设置为20。至于pm.min_spare_servers,则建议根据服务器的负载情况来设置,比如服务器上只是部署php环境的话,比较合适的值在5~10之间。

本服务器配置

1、服务器基本信息:
硬盘:数据盘30G、系统盘20G
内存:1.5G
CPU:双核
系统:CentOS 6.3 64位
带宽:独享2M
2、部署的应用
Git、SVN、Apache、Tomcat、PHP、Nginx、Mysql、JDK
3、优化后的参数
pm = dynamic
pm.start_servers = 5
pm.min_spare_servers = 2
pm.max_spare_servers = 8

 

开启 php-fpm 状态页及状态详解

编辑www.conf 配置文件 找到pm.status_path配置项,取消注释,重载php-fpm

pm.status_path = /phpfpm_status

在nginx.conf加入下面这个location模块,并重载nginx配置

server {
    location /phpfpm_status {
        fastcgi_pass  127.0.0.1:9000;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
    }
}

打开status页面,可以看到以下信息

pool:                 www
process manager:      dynamic
start time:           23/Apr/2019:15:38:06 +0800
start since:          7598
accepted conn:        5
listen queue:         0
max listen queue:     0
listen queue len:     128
idle processes:       1
active processes:     1
total processes:      2
max active processes: 1
max children reached: 0
slow requests:        0

status 信息详解

pool 			– fpm池子名称,大多数为www
process manager 	– 进程管理方式,值:static, dynamic or ondemand. dynamic
start time 		– 启动日期,如果reload了php-fpm,时间会更新
start since 		– 运行时长
accepted conn 		– 当前池子接受的请求数
listen queue 		– 请求等待队列,如果这个值不为0,那么要增加pphp-fpm的进程数量
max listen queue 	– 请求等待队列最高的数量
listen queue len 	– socket等待队列长度
idle processes 		– 空闲进程数量
active processes 	– 活跃进程数量
total processes 	– 总进程数量
max active processes 	– 最大的活跃进程数量(FPM启动开始算)
max children reached 	- 进程最大数量限制的次数,如果这个数量不为0,那说明你的最大进程数量太小了,请改大一点。
slow requests 		– 启用了php-fpm slow-log,缓慢请求的数量

 

status状态页的显示效果,可以有 json、xml、html、full 四种,可以通过 GET 传参显示不同的效果。

1、json 格式

通过访问 http://你的域名/phpfpm_status?json 来显示 json 格式,如:

{"pool":"www","process manager":"dynamic","start time":1556005086,"start since":6634,"accepted conn":2,"listen queue":0,"max listen queue":0,"listen queue len":128,"idle processes":1,"active processes":1,"total processes":2,"max active processes":1,"max children reached":0,"slow requests":0}

2、xml 格式

通过访问 http://你的域名/phpfpm_status?xml来显示 xml 格式,如:

<status>

<pool>www</pool>

<process-manager>dynamic</process-manager>

<start-time>1556005086</start-time>

<start-since>7353</start-since>

<accepted-conn>3</accepted-conn>

<listen-queue>0</listen-queue>

<max-listen-queue>0</max-listen-queue>

<listen-queue-len>128</listen-queue-len>

<idle-processes>1</idle-processes>

<active-processes>1</active-processes>

<total-processes>2</total-processes>

<max-active-processes>1</max-active-processes>

<max-children-reached>0</max-children-reached>

<slow-requests>0</slow-requests>

</status>

3、html 格式

通过访问 http://你的域名/phpfpm_status?html 来显示 html 格式。status页面默认返回的就是 html 格式。

4、full 格式

通过访问 http://你的域名/bcstatus?full 来显示 full 格式,如:

pool:                 www
process manager:      dynamic
start time:           23/Apr/2019:15:38:06 +0800
start since:          7558
accepted conn:        4
listen queue:         0
max listen queue:     0
listen queue len:     128
idle processes:       1
active processes:     1
total processes:      2
max active processes: 1
max children reached: 0
slow requests:        0

************************
pid:                  11990
state:                Running
start time:           23/Apr/2019:15:38:06 +0800
start since:          7558
requests:             2
request duration:     204
request method:       GET
request URI:          /phpfpm_status?full
content length:       0
user:                 -
script:               -
last request cpu:     0.00
last request memory:  0

************************
pid:                  11991
state:                Idle
start time:           23/Apr/2019:15:38:06 +0800
start since:          7558
requests:             2
request duration:     256
request method:       GET
request URI:          /phpfpm_status?xml
content length:       0
user:                 -
script:               -
last request cpu:     0.00
last request memory:  2097152

full 格式参数详解 

pid 			– 进程PID,可以单独kill这个进程.
state 			– 当前进程的状态 (Idle, Running, …)
start time 		– 进程启动的日期
start since 		– 当前进程运行时长
requests 		– 当前进程处理了多少个请求
request duration 	– 请求时长(微妙)
request method 		– 请求方法 (GET, POST, …)
request URI 		– 请求URI
content length 		– 请求内容长度 (仅用于 POST)
user 			– 用户 (PHP_AUTH_USER) (or ‘-’ 如果没设置)
script 			– PHP脚本 (or ‘-’ if not set)
last request cpu 	– 最后一个请求CPU使用率。
last request memorythe  - 上一个请求使用的内存

我们可以通过url请求获取当前时刻php-fpm的进程状态,结合定时任务,做成一个状态监控,通过获取的数据中的 'listen queue' 参数得到请求等待队列长度,这个参数如果不为0,就表示当前进程数被使用完了,新的请求过来必须进入等待队列,所以,通过这个参数,就可以判断是否应该增加进程数或加强服务器配置。

 

 

 

 

 

 

 

<think>好的,我现在需要帮助用户解决PHP文件被下载而不是解析的问题。用户之前已经得到了关于Nginx配置的详细步骤,现在他们想检查PHP-FPM配置。我需要结合用户提供的引用和之前的回答来给出合适的解决方案。 首先,用户的问题明确指向PHP-FPM配置。根据引用[1],PHP-FPM在5.3.3之后已经集成到PHP核心,所以在安装时需要使用--enable-fpm参数。这可能意味着用户需要确认PHP-FPM是否正确安装和运行。不过用户现在的问题不是安装,而是配置,所以可能需要检查PHP-FPM配置是否正确。 接下来,引用[2]提到了Web服务器和PHP-FPM的协作流程。当请求PHP文件时,Nginx应该通过FastCGI将请求转发给PHP-FPM处理。如果PHP-FPM没有正确配置,可能导致Nginx无法正确传递请求,从而让浏览器下载文件。所以需要检查PHP-FPM的监听方式(socket还是端口)、权限设置以及进程管理。 引用[3]提到了ThinkPHP配置,其中需要指定public目录作为运行目录。这可能涉及到Nginx的root和location配置,但用户现在关注的是PHP-FPM,所以可能需要确认PHP-FPM配置是否允许处理这些请求。 用户之前的问题中已经提到了检查PHP-FPM的运行状态、安全限制和日志文件。现在需要更详细地指导用户如何配置PHP-FPM,可能包括确认进程池配置、监听socket的权限、安全参数如security.limit_extensions,以及日志的查看。 可能的步骤包括: 1. 确认PHP-FPM的安装和运行状态。 2. 检查PHP-FPM配置文件(如www.conf)中的监听设置是否正确,是否与Nginx中的fastcgi_pass一致。 3. 确保security.limit_extensions包含.php,防止其他文件被错误解析。 4. 检查文件权限,确保PHP-FPM进程有权限读取PHP文件。 5. 查看PHP-FPM和Nginx的错误日志,寻找可能的错误信息。 6. 测试配置更改后重启服务。 需要注意的是,用户的服务器环境可能不同,比如PHP版本、文件路径等,所以需要给出通用的步骤,同时提醒用户根据实际情况调整。此外,用户可能对某些配置项不熟悉,需要解释关键参数的作用,比如security.limit_extensions和listen.owner等。 另外,用户可能之前已经按照步骤配置了Nginx,但问题依然存在,所以需要强调PHP-FPM与Nginx协作的关键点,比如socket文件的权限和所有权是否正确,确保两者之间的通信正常。例如,Nginx的运行用户(如www-data)需要有权限访问PHP-FPM的socket文件,否则会导致连接失败,进而无法解析PHP文件。 还需要考虑是否PHP-FPM的进程池配置限制了某些目录或文件,导致无法正确执行PHP脚本。此外,检查PHP-FPM是否在处理请求时遇到错误,比如脚本超时或内存不足,但这类问题通常会导致500错误而非下载,所以可能性较低。 最后,总结需要用户逐步检查PHP-FPM的关键配置点,验证与Nginx的连接,确保所有设置一致且正确,然后通过重启服务和测试来确认问题是否解决。</think>### 分步排查与配置 PHP-FPM 以解析 PHP 文件 --- #### **1. 确认 PHP-FPM 基础配置** **核心目标**:确保 PHP-FPM 与 Nginx 通过正确的通信方式(Unix Socket 或 TCP)建立连接,并具备执行 PHP 脚本的权限。 --- ##### **(1)检查 PHP-FPM 进程状态** ```bash sudo systemctl status php-fpm # 通用命令(根据实际版本调整,如 php8.1-fpm) ``` - **预期输出**:`Active: active (running)` - **若未运行**: ```bash sudo systemctl start php-fpm # 启动服务 sudo systemctl enable php-fpm # 设置开机自启 ``` --- ##### **(2)验证 PHP-FPM 监听方式** 编辑 PHP-FPM 进程池配置文件(默认路径:`/etc/php/<version>/fpm/pool.d/www.conf`): ```ini ; 关键配置项: listen = /run/php/php8.1-fpm.sock # 使用 Unix Socket(推荐) ; listen = 127.0.0.1:9000 # 使用 TCP 端口 ; 确保权限允许 Nginx 访问: listen.owner = www-data # 与 Nginx 用户(通常为 www-data)一致 listen.group = www-data listen.mode = 0660 ``` - **关键点**: - `listen` 的值必须与 Nginx 配置中的 `fastcgi_pass` 匹配(如 `unix:/run/php/php8.1-fpm.sock`)[^1]。 - 若使用 TCP 端口,需开放防火墙(如 `ufw allow 9000`)。 --- ##### **(3)安全限制检查** 在同一配置文件中,确认 PHP-FPM 仅解析合法扩展名: ```ini security.limit_extensions = .php .php7 .phar # 必须包含 .php ``` - **若为空**:PHP-FPM 会尝试解析所有文件(如 .html 也被当作 PHP 执行,存在安全风险)[^2]。 --- #### **2. 权限与文件归属配置** ##### **(1)PHP 文件权限** 确保 PHP 脚本可被 Nginx 和 PHP-FPM 读取: ```bash sudo chmod -R 755 /var/www/html # 目录权限 sudo chown -R www-data:www-data /var/www/html # 文件归属(用户:组需与 PHP-FPM/Nginx 一致) ``` ##### **(2)Socket 文件权限** 若使用 Unix Socket,检查 Socket 文件归属: ```bash ls -l /run/php/php8.1-fpm.sock ``` - **预期归属**:`www-data:www-data`,权限 `rw-rw----`(即 0660)。 --- #### **3. 日志排查(定位深层问题)** ##### **(1)PHP-FPM 错误日志** 查看日志路径(通常在 `/var/log/php<version>-fpm.log`): ```bash sudo tail -f /var/log/php8.1-fpm.log ``` - **常见错误**: - `Primary script unknown`:Nginx 未正确传递 `SCRIPT_FILENAME`(需检查 Nginx 配置中的 `fastcgi_param`)。 - `Permission denied`:PHP 文件或 Socket 权限不足。 ##### **(2)Nginx 错误日志** ```bash sudo tail -f /var/log/nginx/error.log ``` - **关键线索**:`connect() failed`(通信失败)或 `access forbidden`(权限问题)。 --- #### **4. 配置关联性验证** ##### **(1)Nginx 与 PHP-FPM 的通信测试** 手动发送 FastCGI 请求验证连通性(需安装 `cgi-fcgi` 工具): ```bash SCRIPT_NAME=/test.php SCRIPT_FILENAME=/var/www/html/test.php REQUEST_METHOD=GET cgi-fcgi -bind -connect unix:/run/php/php8.1-fpm.sock ``` - **预期输出**:返回 PHP 脚本的执行结果(如 `<?php echo "OK"; ?>` 应输出 `OK`)。 ##### **(2)ThinkPHP 特殊配置** 若使用框架(如 ThinkPHP),需确保 Nginx 的 `root` 指向 `public` 目录[^3]: ```nginx root /var/www/html/public; # 示例路径 location / { try_files $uri $uri/ /index.php?$query_string; } ``` --- #### **5. 重载配置并测试** ```bash sudo systemctl reload php-fpm nginx # 平滑重载配置 curl -I http://localhost/test.php # 检查 Content-Type 是否为 text/html ``` - **成功标志**:浏览器访问 PHP 文件时显示页面内容,而非下载。 --- ### 关键配置总结表 | **配置项** | **正确值示例** | **错误后果** | |--------------------------|-----------------------------|---------------------------| | `listen` (PHP-FPM) | `/run/php/php8.1-fpm.sock` | Nginx 无法转发请求 | | `security.limit_extensions` | `.php` | 非 PHP 文件被错误解析 | | `listen.owner` (PHP-FPM) | `www-data` | Socket 通信权限被拒绝 | | `fastcgi_pass` (Nginx) | `unix:/run/php/php8.1-fpm.sock` | PHP 文件直接下载 | --- ### 相关问题 1. 如何为不同的网站配置独立的 PHP-FPM 进程池? 2. 如何调整 PHP-FPM 子进程数量以优化性能? 3. Nginx 返回 `502 Bad Gateway` 时如何排查 PHP-FPM 问题?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值