一般情况下我们搭建前端运行WEB环境时会采用Nginx比较多,使用Nginx作为Web服务器的时候,你或多或少都会遇到Nginx 502 bad gateway的错误,造成这种错误的原因有很多,下面我们来一一解析。
这样的错误提示问题502 Bad Gateway是指错误网关,无效网关;在互联网中表示一种网络错误。表现在WEB浏览器中给出的页面反馈。
含义:这通常并不意味着上游服务器已关闭(无响应网关/代理) ,而是上游服务器和网关/代理不同意的协议交换数据。鉴于互联网协议是相当清楚的,它往往意味着一个或两个机器已不正确或不完全编程。

502系列错误代码

  • HTTP Error 502 Bad Gateway HTTP 错误 502 网关错误
  • HTTP 502
  • 502 Service Temporarily Overloaded 502 服务暂时超载
  • Temporary Error (502) 临时错误 (502)
  • 502 Server Error: The server encountered a temporary error and could not - - complete your request 502 服务器错误:服务器遇到临时错误,无法完成您的请求
  • 502 Bad Gateway Nginx 502 网关坏 Nginx

5XX系列错误代码

  • 500 Internal Server ErrorWeb 服务器遇到遇到阻止其无法完成其任务(即客户端请求)的条件时,将显示此错误
  • 501 Not Implemented 服务器无法支持或识别请求方法。 它缺少处理请求的功能,因此它会响应此错误
  • 502 Bad Gateway 服务器之间发生了错误,充当代理或网关时,您的服务器在尝试处理请求时未收到上游服务器的正确响应
  • 503 Service Unavailable 由于正在进行维护或服务器当前过载而导致服务器无法处理请求的临时情况
  • 504 Gateway Timeout 服务器再次充当代理或网关时,没有及时从另一个服务器(例如DNS)获得响应,因此它无法处理请求
  • 505 HTTP Version Not Supported 当您的Web服务器不能或将不支持源自请求的HTTP协议版本时,将发生他的错误。 该错误通常包含服务器为什么不合作的描述

Nginx 502 Bad Gateway 错误的解决方案

出现nginx 502 bad gateway 问题,先从nginx端日志入手,分析排查原因。

1、代理缓冲区设置过小(使用了nginx反向代理的情况)

首先需要打开nginx错误日志。
编辑nginx.conf,默认路径在/usr/local/nginx/conf/nginx.conf,将错误日志输入到/usr/local/nginx/log/error_nginx.log,更改为info级别。

补充:

  • 错误日志级别:常见的错误日志级别有[debug | info | notice | warn | error | crit | alert | emerg],级别越高记录的信息越少。
  • 生产场景一般是 warn | error | crit 这三个级别之一
  • 注意:不要配置info等级较低的级别,会带来大量的磁盘I/O消耗,问题定位后,请调整日志级别至crit。

点击报错的业务功能,并查看nginx错误日志tail -50f /usr/local/nginx/log/error_nginx.log下面是我遇到的nginx报错,很明显是头部数据太大了 。如果header过大,超出了默认的1k,就会引发upstream sent too big header

此问题解决方案:
在nginx.conf转发的配置上增加,即location下面

1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name *.test.com;

location / {
#添加这3行start
proxy_buffer_size 64k;
proxy_buffers 32 32k;
proxy_busy_buffers_size 128k;
#添加这3行end
}
}

2、检查PHP基础设置

修改/www/server/php/80/etc/php-fpm.conf中的request_terminate_timeout = 100,把100改成5;
php执行超时,修改/usr/local/php/etc/php.inimax_execution_time为300;

3、FastCGI进程是否已经启动

nginx 502错误的含义是sock、端口没被监听造成的。我们先检查fastcgi是否在运行
ps aux | grep php
查看是否启动了php-fpm服务;

4、FastCGI worker进程数是否不够

fastcgi进程数不够用、php执行时间长、或者是php-cgi进程死掉也可能造成nginx的502错误,运行以下命令判断是否接近FastCGI进程,如果fastcgi进程数接近配置文件中设置的数值,表明worker进程数设置太少。

运行linux命令:

1
netstat -anpo | grep “php-cgi” | wc -l

判断是否接近FastCGI进程,接近配置文件中设置的数值,表明worker进程数设置太少;

5、FastCGI执行时间过长

PHP程序执行时间超过了Nginx等待时间,可以适当增加nginx.conf配置文件中FastCGI的timeout时间,根据实际情况调高以下参数值:

1
2
3
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;

6、FastCGI Buffer不够

nginx和apache一样,有前端缓冲限制,可以调整缓冲参数

1
2
fastcgi_buffer_size 32k;
fastcgi_buffers 8 32k;

如果你使用的是nginx的负载均衡Proxying,调整

1
2
proxy_buffer_size 16k;
proxy_buffers 4 16k;

7、FastCGI 缓冲区设置过小

首先查找nginx日志文件,目录/var/log/nginx,在日志中发现了如下错误:
[error] 15421#0: *16 upstream sent too big header while reading response header from upstream意思是nginx缓冲区bug造成。查阅了一下资料,大意是nginx缓冲区有一个bug造成的,我们网站的页面消耗占用缓冲区可能过大。参考老外写的修改办法增加了缓冲区容量大小设置,502问题彻底解决。后来系统管理员又对参数做了调整只保留了2个设置参数:client head buffer,fastcgi buffer size。网站页面占用缓冲区过大。增加缓冲区彻底解决了Nginx 502 Bad Gateway,方法如下:

1
2
3
4
5
6
http {
...
fastcgi_buffers 8 16k;
fastcgi_buffer_size 32k;
...
}

请根据服务器已经网站的情况自行增大上述两个配置项。

8、默认php-cgi的进程数设置过少

一台服务器上运行着nginx php(fpm) xcache,访问量日均 300W pv左右

最近经常会出现这样的情况: php页面打开很慢,cpu使用率突然降至很低,系统负载突然升至很高,查看网卡的流量,也会发现突然降到了很低。这种情况只持续数秒钟就恢复了

检查php-fpm的日志文件发现了一些线索:

1
Sep3008:32:23.289973[NOTICE] fpm_unix_init_main(), line 271: getrlimit(nofile): max:51200,cur:51200 Sep3008:32:23.290212[NOTICE] fpm_sockets_init_main(), line 371:using inherited socket fd=10,“127.0.0.1:9000″ Sep3008:32:23.290342[NOTICE] fpm_event_init_main(), line 109: libevent:using epoll Sep3008:32:23.296426[NOTICE] fpm_init(), line 47: fpm is running, pid 30587

在这几句的前面,是1000多行的关闭children和开启children的日志

原来,php-fpm有一个参数max_requests,该参数指明了,每个children最多处理多少个请求后便会被关闭,默认的设置是500。因为php是把请求轮询给每个children,在大流量下,每个childre到达max_requests所用的时间都差不多,这样就造成所有的children基本上在同一时间被关闭。

在这期间,nginx无法将php文件转交给php-fpm处理,所以cpu会降至很低(不用处理php,更不用执行sql),而负载会升至很高(关闭和开启children、nginx等待php-fpm),网卡流量也降至很低(nginx无法生成数据传输给客户端)

解决问题很简单,增加children的数量,并且将max_requests设置为0或者一个比较大的值:

在安装好使用过程中出现502问题,一般是因为默认php-cgi进程是5个,可能因为phpcgi进程不够用而造成502,需要修改/usr/local/php/etc/php-fpm.conf 将其中的max_children的值适当增加。也有可能是max_requests的值不够用。需要说明的是这连个配置项占用内存很大,请根据服务器配置进行设置。否则可能起到反效果。

9、其它原因

如果您上网时在您尝试访问的所有网站上都看这个问题,有两种可能

①你的ISP重大设备故障/过载

②有问题的内部互联网连接如您的防火墙无法正常运作。

在种情况下,只有您的ISP可以帮助您。在第二种情况下,你需要解决什么,那是阻止你进入互联网。

如果您只有在部分尝试访问的网站中出现此问题,那很可能是一个问题,即这些网站之一,其设备故障或超载。联系你网站的管理员。