Nginx 502 Bad Gateway 的含义是请求的PHP-CGI已经执行,但是由于某种原因(一般是读取资源的问题)没有执行完毕而导致 PHP-CGI 进程终止,一般来说Nginx 502 Bad Gateway和php-fpm.conf的设置有关。
常规办法
常见的原因可能是php-cgi进程数不够用、php执行时间长(mysql慢)、或者是php-cgi进程死掉,都会出现502错误。
- 在安装好的环境中,运行一段时间出现502问题,一般是因为默认php-cgi进程是5个,可能因为phpcgi进程不够用而造成502,需要修改
/usr/local/php/etc/php-fpm.conf
将其中的max_children值适当增加。 - php执行超时,修改
/usr/local/php/etc/php.ini
将max_execution_time
改为300
,设置为0则无限制,脚本会一直执行下去,直到执行结束。 - 磁盘空间不足,可以使用 # df -h命令查看磁盘使用量
- php-cgi进程死掉了。
- 配置出错
- 文件打开数量限制
- 类eAccelerator/opcache/Xcached等PHP性能优化程序不兼容导致的,卸载之即可。 例:
cd ~/lnmp1.5full && ./addons.sh uninstall eAccelerator
通常的排查方法如下:
1、查看php fastcgi的进程数(max_children值)
# netstat -anop | grep php-cgi | wc -l
# netstat -anpo | grep php-fpm | wc -l
假如显示是5
2、查看当前进程
# ps aux | grep php-fpm
观察fastcgi/php-fpm进程数,假如使用的进程数等于或高于5个,说明需要增加。
3、调整/usr/local/php/etc/php-fpm.conf
的相关设置
pm.max_children = 5
request_terminate_timeout = 60
max_children
最多5个进程,按照每个进程20MB内存,最多100MB。也就是1分钟。max_children
增多,则php-cgi的进程多了就会处理的很快,排队的请求就会很少。 但是设置max_children
也需要根据服务器的性能进行设定,一般来说一台服务器正常情况下每一个php-cgi所耗费的内存在20M左右。根据自己服务器购买的内存来实际决定。
request_terminate_timeout
执行的时间为60秒,request_terminate_timeout
值可以根据服务器的性能进行设定。一般来说性能越好你可以设置越高,20分钟-30分钟都可以。
4、部分PHP程序的执行时间超过了Nginx的等待时间,可以适当增加nginx.conf
配置文件中fastcgi
的timeout
时间,例如:
http
{
……
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
……
}
5、减少FastCGI的请求次数,尽量维持buffers不变:
vi /usr/local/nginx/conf/nginx.conf
修改为:
fastcgi_buffer_size 64k;
fastcgi_buffers 2 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 50M;
然后重启Nginx:
/etc/init.d/nginx restart
6、有时候也可能是自己修改过下面2处的配置,导致nginx配置文件里的设置和php-fpm上的设置不一样也会502。如果使用unix套接字,修改/usr/local/php/etc/php-fpm.conf
里设置,php 5.2为:
/tmp/php-cgi.sock
php 5.3及以上版本为listen = /tmp/php-cgi.sock
,同时/usr/local/nginx/conf/nginx.conf
及其/usr/local/nginx/conf/vhost/
下面的虚拟主机配置里的fastcgi_pass unix:/tmp/php-cgi.sock;
不一致就必定502。有时候unix套接字模式下可能会502,可以尝试改成tcp/ip的方式 php 5.2下:
/tmp/php-cgi.sock
替换为
127.0.0.1:9000
php 5.3及以上版本listen = /tmp/php-cgi.sock
替换为listen = 127.0.0.1:9000
,nginx配置文件及虚拟主机配置文件里fastcgi_pass unix:/tmp/php-cgi.sock;
替换为fastcgi_pass 127.0.0.1:9000;
之后重启试试。
7、php打开文件数的限制可能也会导致502错误
编辑 /etc/security/limits.conf
加上:
* soft nofile 65535
* hard nofile 65535
编辑/etc/sysctl.conf
底部添加fs.file-max=65535
再添加到自启动项
echo "ulimit -SHn 65535" >> /etc/rc.local
打开php-fpm.conf
找到 rlimit_files
改成:65535
如果没有rlimit
这项请自己加上
rlimit_files = 65535
重启
/etc/init.d/php-fpm restart
万不得已
如果以上方法均无法解决
替换修改CheckURL的链接地址,复制下面的代码并保存为 check502.sh (使用军哥LNMP一键脚本安装的在tools目录中可以找到)
#!/bin/bash
time="$(date +"%Y%m%d-%H:%M")"
CheckURL="https://yourdomain.com"
STATUS_CODE=`curl -o /dev/null -m 10 --connect-timeout 10 -s -w %{http_code} $CheckURL`
#echo "$CheckURL Status Code:\t$STATUS_CODE"
if [ "$STATUS_CODE" = "502" ]; then
/etc/init.d/php-fpm restart
echo " $time 监测页: $CheckURL 状态码: $STATUS_CODE 行为: 异常&重启" >> /var/log/httpcode.log
fi
赋予sh文件可执行权限
chmod a+x check502.sh
加入cron定时任务
*/2 * * * * bash /路径/check502.sh
重启 cron
service crond restart
脚本将会每隔2分钟运行一次得到状态码502的时候将自动重启 php-fpm.
写在最后
最近因为502的问题伤神,查看日志 -> 推测可能造成问题的原因 -> 修改与测试 ->反复失败。并且502错误出现的时间非常有规律每隔30分钟报错一次。并且都是在半点和整点的时间出现。(通过脚本检测网页状态返回503打印一条日志得到的结果)
最后博主使用排除法,移除 eAccelerator,502错误不再复现。推测初始化安装的 eAccelerator 版本与PHP版本不兼容导致。
文章参考: LNMP一键安装包的Nginx 502 Bad Gateway错误可能原因及解决方法
相关推荐
- ngx_waf:一款高大全的 Nginx 网站防火墙模块
- LNMP 编译安装 ngx_pagespeed 模块给网站提速!
- 群晖NAS | PHP如何添加Acpu/Redis/Memcached等扩展?
- 如何彻底禁止百度等搜索引擎收录
- Nginx 查看并发连接数的两种方法
- 解决Nginx出现“Too many open files”的问题
文章作者:喵斯基部落
原文地址:https://www.moewah.com/archives/618.html
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。非商业转载及引用请注明出处(作者、原文链接),商业转载请联系作者获得授权。