502.jpg

Nginx 502 Bad Gateway 的含义是请求的PHP-CGI已经执行,但是由于某种原因(一般是读取资源的问题)没有执行完毕而导致 PHP-CGI 进程终止,一般来说Nginx 502 Bad Gateway和php-fpm.conf的设置有关。

常规办法

常见的原因可能是php-cgi进程数不够用、php执行时间长(mysql慢)、或者是php-cgi进程死掉,都会出现502错误。

  1. 在安装好的环境中,运行一段时间出现502问题,一般是因为默认php-cgi进程是5个,可能因为phpcgi进程不够用而造成502,需要修改/usr/local/php/etc/php-fpm.conf 将其中的max_children值适当增加。
  2. php执行超时,修改/usr/local/php/etc/php.inimax_execution_time 改为300,设置为0则无限制,脚本会一直执行下去,直到执行结束。
  3. 磁盘空间不足,可以使用 # df -h命令查看磁盘使用量
  4. php-cgi进程死掉了。
  5. 配置出错
  6. 文件打开数量限制
  7. 类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

SFREoNpCMzXiqvNXxdWV.jpg

假如显示是5

2、查看当前进程

# ps aux | grep php-fpm 

观察fastcgi/php-fpm进程数,假如使用的进程数等于或高于5个,说明需要增加。

UeBYHGHfmQGhoNsADwGA.jpg

3、调整/usr/local/php/etc/php-fpm.conf 的相关设置

pm.max_children = 5
request_terminate_timeout = 60

dOsNykUMFyItaIPyJySM.jpg

mYechAKxMdexmTFSdflR.jpg

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配置文件中fastcgitimeout时间,例如:

http
{
……
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
……
}

OBTCYcRltQvmLaZDiIMA.jpg

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错误可能原因及解决方法


相关推荐

  1. ngx_waf:一款高大全的 Nginx 网站防火墙模块
  2. LNMP 编译安装 ngx_pagespeed 模块给网站提速!
  3. 群晖NAS | PHP如何添加Acpu/Redis/Memcached等扩展?
  4. 如何彻底禁止百度等搜索引擎收录
  5. Nginx 查看并发连接数的两种方法
  6. 解决Nginx出现“Too many open files”的问题
文章作者:喵斯基部落
原文地址:https://www.moewah.com/archives/618.html
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。非商业转载及引用请注明出处(作者、原文链接),商业转载请联系作者获得授权。