解决nginx+php(php-fpm)出现502 bad gateway问题

本文介绍了解决Nginx出现502错误的多种方法,包括调整php-fpm配置、优化Nginx设置、增加系统文件句柄并发限制等。适用于因后端处理不当导致的Nginx 502错误。

nginx出现502有很多原因,但大部分原因可以归结为资源数量不够用,也就是说后端php-fpm处理有问题,nginx将正确的客户端请求发给了后端的php-fpm进程,但是因为php-fpm进程的问题导致不能正确解析php代码,最终返回给了客户端502错误。

nginx+php出现502 bad gateway,一般这都不是nginx的问题,而是由于 fastcgi或者php的问题导致的,常见的有以下几种(其实解决问题的最好的方式还是自己去看nginx和fastcgi的errorlog):


1. php.ini的memory_limit 过小(如果有个别php程序进程需要占用极大内存时这个必须注意)

2. php-fpm.conf中max_children或者max_requests  设置不合理(设置过小会因为没有足够的cgi进程处理请求,设置过大会出现一会儿有响应正常,一会儿等很久才有响应的情况,一般情况下children按 照内存计算,比如说1G设置64,2G128。这个根据实际情况自行调整。另外查看当前的PHP FastCGI进程数是否够用的命令为:netstat  -anpo |grep “php-cgi” | wc -l   如果实际使用的“FastCGI进程数”接近预设的“FastCGI进程数”,那么,说明“FastCGI进程数”不够用,需要增大。)

3. 查看nginx错误日志,发现 pstream sent too big header while reading response  headerfrom upstream ,则检查client head buffer,fastcgi buffer  size是否过小,可设置为32K。

4. php程序执行时间过长而超时,检查nginx和fastcgi中各种timeout设置。(nginx 中的  fastcgi_connect_timeout 300;fastcgi_send_timeout 300  :fastcgi_read_timeout300; keepalive_timeout ;  php-fpm中的request_terminate_timeout,php.ini中的max_execution_time)


5. php-fpm有一个参数 max_requests ,该参数指明了每个children最多处理多少个请求后便会被关闭。在大量处理请求下,如果该值设置过小会导致children频繁的自杀和建立而浪费 大量时间,若所有的children差不多都在这个时候自杀,则重建前将没有children响应请求,于是出现502  。可以将该值设置大一些或者是0[无限]。

如果你服务器并发量非常大,那只能先增加机器,然后按以下方式优化会取得更好效果;但如果你并发不大却出现502,一般都可以归结为配置问题,脚本超时问题。

1.php-fpm进程数不够用

使用netstat -napo |grep "php-fpm" | wc -l查看一下当前fastcgi进程个数,如果个数接近conf里配置的上限,就需要调高进程数。

但也不能无休止调高,可以根据服务器内存情况,可以把php-fpm子进程数调到100或以上,在4G内存的服务器上200就可以。

2. 调高调高linux内核打开文件数量

可以使用这些命令(必须是root帐号)

echo 'ulimit -HSn 65536'>> /etc/profile

echo 'ulimit -HSn 65536'>> /etc/rc.local

source /etc/profile

 3.脚本执行时间超时

如果脚本因为某种原因长时间等待不返回,导致新来的请求不能得到处理,可以适当调小如下配置。

nginx.conf里面主要是如下

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;

php-fpm.conf里如要是如下

request_terminate_timeout =10s

4.缓存设置比较小

修改或增加配置到nginx.conf

proxy_buffer_size 64k;
proxy_buffers  512k;
proxy_busy_buffers_size 128k;

5. recv()failed (104: Connection reset by peer) while reading response header fromupstream

可能的原因机房网络丢包或者机房有硬件防火墙禁止访问该域名

但最重要的是程序里要设置好超时,不要使用php-fpm的request_terminate_timeout,

最好设成request_terminate_timeout=0;

因为这个参数会直接杀掉php进程,然后重启php进程,这样前端nginx就会返回104: Connection reset by peer。这个过程是很慢,总体感觉就是网站很卡。

May 01 10:50:58.044162[WARNING] [pool www] child 4074, script'/usr/local/nginx/html/quancha/sameip/detail.php' execution timed out(15.129933 sec), terminating
May 01 10:50:58.045725 [WARNING] [pool www] child 4074 exited on signal 15SIGTERM after 90.227060 seconds from start
May 01 10:50:58.046818 [NOTICE] [pool www] child 4082 started

说一千道一万最重要的就是程序里控制好超时,gethostbyname、curl、file_get_contents等函数的都要设置超时时间。

另一个就是多说,这个东西是增加了网站的交互性,但是使用的多了反应就慢了,如果你网站超时且使用了多说是,可以关闭它。

6、自己遇到502的解决办法:

调整增大php 和Nginx 的backlog数。

PHP-FPM高负载的解决办法

Postedon 2011/09/02

这里只是介绍了php-fpm的优化方法的,但一般情况下和nginx组合使用的时候,单独优化其中一项的话,作用不是特别的大,同时还需要对nginx进行优化.nginx的做法方法参考:http://blog.haohtml.com/archives/6213.上面的优化前和优化后的图,看得出前后差距还是特别的大的.

导致nginx 502 bad gateway的PHP-CGI(FASTCGI)

NGINX频爆502 BAD GATEWAY的错误,看了网上的教程,仍没有彻底解决。
目前我总结的解决502 BAD GATEWAY的方式有:

1.视服务器的性能,在php-fmp.conf里增加max_children的值:

max_children是PHP-FPM Pool 最大的子进程数,他数值取决于你的服务器内存。 假设你打算给10G内存给当前配置的PHP-FPM Pool,一般一个PHP请求占用内存10M-40M,我们按站点每个PHP请求占用内存25M,这样max_children = 10G/25M = 409。所以,这个值可以根据情况算出来

max_requests是每个子进程重生之前处理的请求数, 默认值为unlimited(默认为1024),可以设置小一点(如500左右),这样可以避免内存泄露带来的问题

Nginx代理过程,将业务服务器请求数据缓存到本地文件,再将文件数据转发给请求客户端。高并发的客户端请求,必然要求服务器文件句柄的并发打开限制。使用ulimit命令(ulimit -n),查看Linux系统文件句柄并发限制,默认是1024,我们可以改为65535(2 的 16 次方,这是系统端口的极限)。修改的方法为:修改系统文件/etc/security/limits.conf,添加如下信息,并重新启动系统生效。

* soft   nofile  65535

* hard   nofile  65535

然后在Nginx配置文件中,把文件限制及连接数信息改为65535:

worker_rlimit_nofile 65535;
events {
    use epoll;
    worker_connections  65535;
}

2.reload参数定时重载php-fpm。这个主要原因是php脚本执行时间过长造成的,重载php-fpm能杜绝这个问题。如何彻底解决php-cgi脚本占用大量内存从而导致502错误的产生还值得进一步探讨,目前该做法不失为一种好办法。
具体的做法是,用crontabphp-fpm平滑重启,从而不影响PHP脚本的运行。

*/10* * * * /usr/local/php/sbin/php-fpm reload

=================== 优化设置=========================


如果您高负载网站使用PHP-FPM管理FastCGI,这些技巧也许对您有用:)

1.Compile PHP’s modules as less as possible, the simple the best (fast);
1.尽量少安装PHP模块,最简单是最好(快)的

2. Increas PHP FastCGI child number to 100 and even more.Sometime, 200 is OK! ( On 4GB memory server);

2.把您的PHP FastCGI子进程数调到100或以上,在4G内存的服务器上200就可以
注:我的1g测试机,开64个是最好的,建议使用压力测试获取最佳值

3.Using SOCKET PHP FastCGI, and put into /dev/shm on Linux;
3.使用socket连接FastCGI,linux操作系统可以放在/dev/shm中
注:在php-fpm.cnf里设置<valuename=”listen_address”>/tmp/nginx.socket</value>就可以通过socket连接FastCGI了,/dev/shm是内存文件系统,放在内存中肯定会快了.记得这时也要在nginx里的配置里进行修改,保持一致.

location~ .*/.(php|php5)?$

{

#

将Nginx与FastCGI的通信方式由TCP改为UnixSocket。TCP在高并发访问下比UnixSocket稳定,但Unix Socket速度要比TCP快。

fastcgi_pass  unix:/tmp/php-cgi.sock;

#fastcgi_pass  127.0.0.1:9000;

fastcgi_index index.php;

include fcgi.conf;

}

4. Increase Linux “max open files”, using the following command(must be root):

# echo ‘ulimit -HSn 65536′>> /etc/profile

# echo ‘ulimit -HSn 65536 >> /etc/rc.local

# source /etc/profile 


4.调高linux内核打开文件数量,可以使用这些命令(必须是root帐号

)

echo ‘ulimit -HSn 65536′ >> /etc/profile

echo ‘ulimit -HSn 65536′ >> /etc/rc.local

source /etc/profile 


注:我是修改/etc/rc.local,加入ulimit -SHn 51200

5.Increase PHP-FPM open file description rlimit:

# vi /path/to/php-fpm.conf

Find “<value name=”rlimit_files”>1024</value>”

Change 1024 to 4096 or higher number.

Restart PHP-FPM.


5.增加 PHP-FPM 打开文件描述符的限制

# vi /path/to/php-fpm.conf

找到

“<value name=”rlimit_files”>1024</value>”

1024更改为4096或者更高

.

重启PHP-FPM.

6. Using PHP code accelerator,e.g eAccelerator, XCache. And set “cache_dir” to /dev/shm on Linux.
6.使用php代码加速器,例如eAccelerator, XCache.在linux平台上可以把`cache_dir`指向/dev/shm

<think>我们正在解决nginxphp-fpm配置下PHP文件无法解析的问题。根据提供的引用信息,我们可以从配置和资源两个主要方面来排查。引用[1]提到Nginx通过FastCGI将PHP请求转发到PHP-FPM服务器,引用[3]详细说明了NginxPHP-FPM的配置文件位置和作用,引用[2]和[4]则分析了502错误的原因,包括资源不足和PHP-FPM进程问题问题现象:访问PHP文件时,可能返回空白页面、502错误或者直接下载PHP文件(而不是解析执行)。排查步骤:1.检查Nginx配置:确保Nginx正确配置了PHP文件的处理,即对于.php请求,应该转发给PHP-FPM处理。在Nginx的server块中,应该有类似以下配置:```location~\.php${fastcgi_passmy_stack_php:9006;#这里应该是PHP-FPM的地址和端口,可以是IP:端口,也可以是unixsocketfastcgi_indexindex.php;includefastcgi_params;fastcgi_paramSCRIPT_FILENAME$document_root$fastcgi_script_name;}```注意:`fastcgi_pass`的值必须与PHP-FPM配置的监听地址一致(见步骤2)。特别重要的是`fastcgi_paramSCRIPT_FILENAME`,它告诉PHP-FPM要执行哪个文件。如果这个参数设置错误,PHP-FPM可能找不到文件,从而返回空白页面或404。2.检查PHP-FPM配置:在PHP-FPM的配置文件(如www.conf)中,检查监听设置(listen)是否与Nginx配置中的`fastcgi_pass`一致。例如,如果PHP-FPM配置为监听9006端口:```listen=9006```或者使用unixsocket:```listen=/var/run/php/php7.4-fpm.sock```同时,确保PHP-FPM的监听地址(IP和端口或socket文件)是可访问的,并且Nginx有权限访问(特别是使用unixsocket时,注意文件权限)。3.检查文件路径和权限:确保NginxPHP-FPM进程对PHP文件所在的目录有读取权限,对目录有执行权限(至少需要x权限才能进入目录)。同时,PHP-FPM进程需要对文件有执行权限(因为要执行PHP脚本)。通常,NginxPHP-FPM运行的用户可能不同(如Nginx运行用户为nginxPHP-FPM运行用户为www-data),需要确保两个用户都有适当的权限。4.检查资源限制:引用[2]提到资源数量不够用可能导致502错误。检查PHP-FPM的进程管理配置(在www.conf中),例如:-pm.max_children:最大子进程数,如果设置过小,在高并发时可能不够用。-pm.start_servers:启动时的子进程数。-pm.min_spare_servers/pm.max_spare_servers:空闲进程的最小和最大数量。如果进程数不足,请求会被堆积,超过Nginx等待时间(fastcgi_read_timeout)就会返回502。5.检查错误日志:查看Nginx错误日志和PHP-FPM错误日志,通常可以找到具体原因。-Nginx错误日志:在Nginx配置文件中(如nginx.conf)的error_log指令定义。-PHP-FPM错误日志:在PHP-FPM配置文件(www.conf或php-fpm.conf)中的error_log指令定义。6.测试PHP-FPM:可以通过命令行发送一个测试请求到PHP-FPM,检查其是否正常工作。例如,使用cgi-fcgi工具(需要安装):```SCRIPT_NAME=/path/to/your/test.phpSCRIPT_FILENAME=/path/to/your/test.phpREQUEST_METHOD=GETcgi-fcgi-bind-connect127.0.0.1:9006```或者使用telnet(如果是TCP连接):```telnet127.0.0.19006```然后输入FastCGI请求(比较复杂,推荐使用工具)。7.检查SELinux或AppArmor:如果系统启用了SELinux或AppArmor,可能会阻止NginxPHP-FPM的某些操作。可以暂时禁用SELinux(`setenforce0`)或查看相关日志(/var/log/audit/audit.log)来排查。8.检查防火墙:确保Nginx服务器和PHP-FPM服务器(如果分开部署)之间的端口(如9006)是开放的。常见问题总结:-配置不一致:Nginx的fastcgi_pass与PHP-FPM的listen不一致。-权限问题NginxPHP-FPM用户对PHP文件或目录没有权限。-SCRIPT_FILENAME设置错误:在Nginx配置中,$document_root变量可能为空,或者路径错误。可以尝试使用绝对路径,例如:`fastcgi_paramSCRIPT_FILENAME/var/www/html$fastcgi_script_name;`-PHP-FPM进程池问题:进程池配置过小,无法处理请求。-超时设置:Nginx的fastcgi_read_timeout设置过短,而PHP脚本执行时间过长,可以适当增加。根据引用[4],PHP-FPM的工作模式是多进程单线程,每个进程同时只能处理一个请求。如果所有工作进程都在忙碌(比如执行长时间任务或阻塞在I/O上),新的请求就会被阻塞,直到有进程空闲。因此,合理配置进程数(pm.max_children)和优化PHP脚本(减少阻塞时间)也很重要。如果按照以上步骤排查,通常可以解决PHP文件不解析的问题。</think>### 解决NginxPHP-FPM不解析PHP文件的方法 PHP文件无法解析通常由配置错误或权限问题引起。以下是系统化的排查步骤和解决方案,基于NginxPHP-FPM协作原理[^3][^4]: --- #### 一、核心配置检查 1. **Nginx配置验证** 确保`nginx.conf`中PHP处理配置正确(关键参数): ```nginx location ~ \.php$ { fastcgi_pass my_stack_php:9006; # 必须与PHP-FPM端口一致[^1] fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # 最常出错的参数 fastcgi_intercept_errors on; } ``` - **重点检查**:`fastcgi_pass`地址/端口是否匹配PHP-FPM的`www.conf`中`listen`值[^3] - **致命错误**:若`SCRIPT_FILENAME`未设置或路径错误,Nginx会返回空白页或下载PHP文件。 2. **PHP-FPM配置验证** 检查`php/fpm-pool.d/www.conf`: ```ini listen = 9006 # 需与Nginx的fastcgi_pass一致 user = www-data # 必须与Nginx运行用户相同 group = www-data listen.owner = www-data # Socket权限设置 listen.group = www-data pm.max_children = 50 # 进程不足会导致502错误[^2][^4] ``` --- #### 二、权限问题排查 1. **文件所有权** PHP文件需被NginxPHP-FPM进程用户访问: ```bash chown -R www-data:www-data /var/www/html # 统一用户组 chmod 750 /var/www/html # 目录需执行权限 ``` 2. **SELinux/AppArmor** 若启用安全模块,添加规则: ```bash setsebool -P httpd_can_network_connect on # CentOS aa-complain /usr/sbin/nginx # Ubuntu ``` --- #### 三、进程与资源诊断 1. **PHP-FPM进程状态** 检查进程是否存活: ```bash systemctl status php-fpm # 查看服务状态 ps aux | grep php-fpm # 确认进程存在 ``` 2. **资源瓶颈排查** - **502错误**:通常是PHP-FPM进程耗尽[^2][^4] ```bash netstat -anp | grep 9006 | wc -l # 查看活跃连接数 ``` - **优化方案**: ```ini pm = dynamic pm.max_children = 50 # 根据内存调整(每进程约30MB) pm.start_servers = 5 pm.min_spare_servers = 2 pm.max_spare_servers = 8 ``` --- #### 四、高级调试技巧 1. **日志分析** - Nginx错误日志:`/var/log/nginx/error.log` - PHP-FPM日志:`/var/log/php-fpm.log`(需在`www.conf`中启用`catch_workers_output=yes`) 2. **手动测试FastCGI** 使用`cgi-fcgi`工具直接验证PHP-FPM: ```bash SCRIPT_NAME=/test.php SCRIPT_FILENAME=/var/www/html/test.php \ cgi-fcgi -bind -connect 127.0.0.1:9006 ``` 3. **基础测试脚本** 创建`/var/www/html/test.php`: ```php <?php phpinfo(); ?> ``` 访问`http://server/test.php`,若显示PHP信息则配置成功。 --- #### 五、常见故障场景 | 现象 | 可能原因 | 解决方案 | |---------------------|----------------------------|----------------------------| | 直接下载PHP文件 | Nginx未关联PHP处理器 | 检查`location ~ \.php$`配置 | | 空白页无错误 | `SCRIPT_FILENAME`路径错误 | 确认`$document_root`有效性 | | 502 Bad Gateway | PHP-FPM进程崩溃或端口不通 | 检查端口监听`netstat -tuln` | | 504 Gateway Timeout | PHP脚本执行超时 | 调整`fastcgi_read_timeout` | > **关键提示**:修改配置后必须重启服务 > ```bash > nginx -t && systemctl reload nginx # 重载Nginx > systemctl restart php-fpm # 重启PHP-FPM > ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值