Nginx处理静态文件的速度非常快,但它本身不具备解析PHP脚本的能力。要让Nginx运行PHP程序,必须借助FastCGI协议把请求转交给后端的PHP-FPM服务。这个过程中,Nginx充当反向代理和静态资源服务器,PHP-FPM则作为FastCGI进程管理器常驻后台,维护一批PHP解释进程等待请求。配置的关键在于让Nginx把以.php结尾的请求准确转发给PHP-FPM,同时传递足够的脚本路径、请求参数等环境变量,否则就会出现文件找不到或网关错误。

一、FastCGI与PHP-FPM的工作机制
FastCGI是CGI的改进版本。传统CGI每处理一个请求就启动一个进程,请求结束后进程销毁,频繁创建销毁会消耗大量系统资源。FastCGI则让进程常驻内存,请求通过套接字或TCP连接发送给常驻进程,处理完毕后进程继续等待下一个请求,大大降低了开销。PHP-FPM就是PHP官方提供的FastCGI进程管理器,它采用Master-Worker模型,主进程负责管理子进程数量,子进程负责实际执行PHP代码。
Nginx收到一个请求后,会先根据配置文件中的location规则判断该请求是否匹配PHP脚本。如果匹配成功,Nginx会通过fastcgi_pass指定的地址与PHP-FPM建立连接,并把请求方法、URI、查询字符串、脚本路径等信息以FastCGI参数的形式发送过去。PHP-FPM根据这些参数找到对应的PHP文件,执行后把输出结果返回给Nginx,Nginx再把结果响应给客户端。整个链路中任何一个环节出错,都可能导致页面无法正常显示。
常见的异常现象包括502 Bad Gateway、504 Gateway Timeout以及File not found。502通常意味着Nginx无法连接PHP-FPM,比如PHP-FPM没有启动或监听地址不对;504则往往是PHP脚本执行超时或PHP-FPM没有足够空闲进程;File not found大多与脚本路径映射错误有关。理解了工作机制,再排查这些问题就会更有思路。
二、Nginx核心FastCGI指令详解
要让Nginx正确转发PHP请求,首先需要配置一个匹配PHP文件的location块。通常使用正则表达式location ~ \.php$来捕获所有以.php结尾的请求。在这个location内部,必须包含include fastcgi_params或引入发行版预置的fastcgi配置片段,然后设置fastcgi_pass指向PHP-FPM监听地址。fastcgi_index用于指定默认索引文件,如果URI以目录形式访问,则会使用该文件。
最关键的一个参数是SCRIPT_FILENAME。它告诉PHP-FPM要执行哪一个具体的PHP文件。正确写法通常是fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;。其中$document_root是server或location中root指令定义的文档根目录,$fastcgi_script_name是脚本名称。如果只写了$fastcgi_script_name而没有拼接根目录,PHP-FPM会在其工作目录下寻找该文件,很容易出现File not found。很多教程会直接引入snippets/fastcgi-php.conf,这个文件已经包含了正确的SCRIPT_FILENAME设置,但了解底层含义仍然很有必要。
除了上述参数之外,还有几个指令值得关注。fastcgi_split_path_info用于拆分PATH_INFO,适合一些框架的URL路由需求;fastcgi_read_timeout控制Nginx等待PHP-FPM响应的时长,默认60秒,处理长任务时可以适当调大;fastcgi_buffers和fastcgi_buffer_size用于调整响应缓冲区大小。一般小型应用保持默认即可,如果返回内容较大,可以通过调整这些参数避免缓冲区不足。
三、完整配置示例与验证
下面是一份完整的Nginx server配置示例。它假设PHP-FPM通过Unix socket监听在本机,网站根目录为/var/www/html。配置中通过try_files指令将不存在的静态文件请求转发给index.php,这是许多PHP框架需要的统一入口模式。
server {
listen 80;
server_name ippipp.com;
root /var/www/html;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
对应的PHP-FPM池配置文件通常位于/etc/php-fpm.d/www.conf,需要确保监听地址与Nginx配置一致。如果使用Unix socket,还要注意socket文件的属主和权限必须允许Nginx worker进程访问。下面是一个简化的池配置示例。
[www] user = www-data group = www-data listen = /run/php/php-fpm.sock listen.owner = www-data listen.group = www-data listen.mode = 0660 pm = dynamic pm.max_children = 20 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 10
完成配置后,可以先检查Nginx配置语法是否正确。语法检查通过后重新加载服务,然后在网站根目录创建一个测试文件,例如test.php,内容为PHP探针。访问该文件如果能看到PHP环境信息,说明Nginx和PHP-FPM之间的FastCGI通信已经打通。
<?php phpinfo(); ?>
四、Unix socket与TCP socket的选择
Nginx连接PHP-FPM时可以选用Unix socket,也可以选用TCP socket。Unix socket使用本地文件路径作为通信地址,例如unix:/run/php/php-fpm.sock。由于Unix socket不经过网络协议栈,只是内核内部的进程间通信,性能通常比TCP socket稍好,延迟更低。在Nginx和PHP-FPM运行在同一台服务器上时,优先推荐使用Unix socket。
使用Unix socket时,权限配置容易被忽略。Nginx的worker进程运行用户通常是www-data或nginx,PHP-FPM的运行用户也必须匹配。socket文件需要允许双方用户读写,常见权限设置为0660,并通过listen.owner和listen.group明确归属。如果权限不足,Nginx连接socket时会返回Permission denied,进而出现502错误。
当Nginx和PHP-FPM分别部署在不同主机上,或者在容器编排环境中需要通过IP通信时,就应该使用TCP socket。配置方式为fastcgi_pass 127.0.0.1:9000;,PHP-FPM池中对应设置listen = 127.0.0.1:9000。TCP socket便于跨主机扩展,也方便与负载均衡器配合,但会经过网络栈,性能略低于Unix socket。对于开放性端口,还需要配合防火墙限制访问来源,避免PHP-FPM端口暴露在公网。
五、常见报错与性能调优
遇到502 Bad Gateway时,可以先查看Nginx错误日志,通常会记录connect() failed或upstream错误。常见原因是PHP-FPM未启动、socket路径写错、socket权限不足或TCP端口被占用。如果PHP-FPM进程正常,还可以检查Nginx和PHP-FPM的运行用户是否一致,以及socket文件是否存在。用curl -I或浏览器访问测试脚本,结合日志能快速定位问题。
File not found是另一个高频错误。多数情况下是SCRIPT_FILENAME没有拼接完整路径,或者root指令设置的文档根目录和实际PHP文件所在目录不一致。可以通过在fastcgi_params中明确写死绝对路径进行测试,也可以临时开启PHP-FPM的访问日志,查看它实际收到的脚本路径,从而修正映射关系。
性能调优方面,PHP-FPM的进程管理方式直接影响并发处理能力。pm = dynamic适合大多数场景,让主进程根据负载自动调整子进程数量;pm = static固定进程数,适合高并发且资源明确的场景;pm = ondemand按需生成进程,适合低流量或开发环境。pm.max_children不应该设置得过大,每个PHP子进程都会占用内存,过多会导致服务器OOM。可以根据单进程内存占用和服务器可用内存来估算合理值。
此外,开启PHP的OPcache扩展可以显著减少每次请求的脚本编译开销。对于执行较慢的请求,可以在PHP-FPM池中配置slowlog和request_slowlog_timeout,将执行时间过长的请求记录到慢日志中,帮助定位性能瓶颈。安全方面,建议不要在location ~ \.php$之外执行PHP文件,并合理使用try_files避免解析漏洞,同时隐藏PHP版本信息,减少暴露面。
Nginx FastCGIPHP-FPM配置优化修改时间:2026-08-30 00:15:26