http请求流程:一般情况下,提交动态请求的时候,nginx会直接把 请求转交给php-fpm,而php-fpm再分配php-cgi进程来处理相关的请求,之后再依次返回,最后由nginx把结果反馈给客户端浏览器。

Nginx 502 Bad Gateway错误是FastCGI有问题

解决办法

遇到502问题,可以优先考虑按照以下两个步骤去解决。

、查看当前的PHP FastCGI进程数是否够用(max_children值)
netstat -anpo | grep "php-cgi"| wc -l
如果实际使用的“FastCGI进程数”接近预设的“FastCGI进程数”,那么,说明“FastCGI进程数”不够用,需要增大。

、部分PHP程序的执行时间超过了Nginx的等待时间(php内存不足)
增加nginx.conf配置文件中FastCGI的timeout时间,例如:
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300
; php.ini中的memory_limit=64M,重启nginx。
如果这样修改了还解决不了问题,可以参考下面这些方案:

、max-children和max-requests
一台服务器上运行着nginx php(fpm) xcache,访问量日均 300W pv左右
最近经常会出现这样的情况:
php页面打开很慢,cpu使用率突然降至很低,系统负载突然升至很高,查看网卡的流量,也会发现突然降到了很低。这种情况只持续数秒钟就恢复了
检查php-fpm的日志文件发现了一些线索: Sep3008::23.289973[NOTICE] fpm_unix_init_main(), line : getrlimit(nofile): max:,cur:
Sep3008::23.290212[NOTICE] fpm_sockets_init_main(), line :using inherited socket fd=,“127.0.0.1:″
Sep3008::23.290342[NOTICE] fpm_event_init_main(), line : libevent:using epoll
Sep3008::23.296426[NOTICE] fpm_init(), line : fpm is running, pid 在这几句的前面,是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 设置未 或者一个比较大的值: 打开 /usr/local/php/etc/php-fpm.conf 调大以下两个参数(根据服务器实际情况,过大也不行) <valuename=”max_children”></value>
<valuename=”max_requests”></value> 然后重启php-fpm。
、增加缓冲区容量大小
将nginx的error log打开,发现“pstream sent too big header while reading response header from upstream”这样的错误提示。
查阅了一下资料,大意是nginx缓冲区有一个bug造成的,我们网站的页面消耗占用缓冲区可能过大。参考老外写的修改办法增加了缓冲区容量大小设置,502问题彻底解决。
后来系统管理员又对参数做了调整只保留了2个设置参数:client head buffer,fastcgi buffer size。

、request_terminate_timeout
如果主要是在一些post或者数据库操作的时候出现502这种情况,而不是在静态页面操作中常见,那么可以查看一下php-fpm.conf设置中的一项:
request_terminate_timeout 这个值是max_execution_time,就是fast-cgi的执行脚本时间。
0s为关闭,就是无限执行下去。(当时装的时候没仔细看就改了一个数字) 优化fastcgi中,还可以改改这个值5s 看看效果
php-cgi进程数不够用、php执行时间长、或者是php-cgi进程死掉,都会出现502错误。

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

php-fpm.conf有两个至关重要的参数,一个是max_children,另一个是request_terminate_timeout,但是这个值不是通用的,而是需要自己计算的。在安装好使用过程中出现502问题,一般是因为默认php-cgi进程是5个,可能因为php-cgi进程不够用而造成502,需要修改/usr/local/php/etc/php-fpm.conf 将其中的max_children值适当增加。

计算的方式如下:

如果你的服务器性能足够好,且宽带资源足够充足,PHP脚本没有系循环或BUG的话你可以直接将 request_terminate_timeout设置成0s。0s的含义是让PHP-CGI一直执行下去而没有时间限制。而如果你做不到这一点,也就 是说你的PHP-CGI可能出现某个BUG,或者你的宽带不够充足或者其他的原因导致你的PHP-CGI假死那么就建议你给 request_terminate_timeout赋一个值,这个值可以根据服务器的性能进行设定。一般来说性能越好你可以设置越高,20分钟-30分 钟都可以。而max_children这个值又是怎么计算出来的呢?这个值原则上是越大越好,php-cgi的进程多了就会处理的很快,排队的请求就会很少。 设置max_children也需要根据服务器的性能进行设定,一般来说一台服务器正常情况下每一个php-cgi所耗费的内存在20M左右

按照官方的答案,排查了相关的可能,并结合了网友的答案,得出了下面的解决办法。

1、查看php fastcgi的进程数(max_children值)

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

5(假如显示5)

2、查看当前进程

top观察fastcgi进程数,假如使用的进程数等于或高于5个,说明需要增加(根据你机器实际状况而定)

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

<value name=”max_children”>10</value><value name=”request_terminate_timeout”>60s</value>max_children最多10个进程,按照每个进程20MB内存,最多200MB。request_terminate_timeout执行的时间为60秒,也就是1分钟。

nginx报错502的更多相关文章

  1. 压测引起的 nginx报错 502 no live upstreams while connecting to upstream解决

    对系统的某个接口进行极限压测,随着并发量上升,nginx开始出现502 no live upstreams while connecting to upstream的报错,维持最大并发量一段时间,发现 ...

  2. nginx 报错502Bad Gateway

    场景: 目前在ECS中起了多个node服务,使用forever进程守护,最近,打开线上页面发现报错502 Bad Gateway;同时部分静态资源访问不到.(之前可以的): 解决: 首先查看nginx ...

  3. tengine2.2.3报错502的The proxy server received an invalid response from an upstream server问题处理

    tengine2.2.3报错502的The proxy server received an invalid response from an upstream server问题处理 现象:访问订单的 ...

  4. nginx 报错 upstream timed out (110: Connection timed out)解决方案【转】

    转自 nginx 报错 upstream timed out (110: Connection timed out)解决方案 - 为程序员服务http://outofmemory.cn/code-sn ...

  5. nginx报错:./configure: error: C compiler cc is not found, gcc 是已经安装了的

    源码安装nginx报错,找不到gcc,但是实际上gcc是存在的,如下: # ./configure checking for OS + Linux -.el7.x86_64 x86_64 checki ...

  6. nginx报错zero size shared memory zone one

    为了限速,在虚拟主机中加上了一个参数:limit_conn one 1:结果导致重启nginx报错: zero size shared memory zone "one"解决办法是 ...

  7. nginx报错:403 Forbidden 并且访问首页index.php是下载文件的状态

    nginx报错:403 Forbidden 并且访问首页index.php是下载文件的状态,不能正常解析php 系统有其他两个站访问是正常的 看日志没有看到明显的错误 搜索了下: 答案如下: php的 ...

  8. Centos下yum安装Nginx报错 No package nginx available.

    在Centos6下使用yum安装Nginx报错 解决方案: yum install epel-release

  9. 安装Nginx报错“Cannot retrieve metalink for repository: epel. Please verify its path and try again”

    CentOS 6.5中通过yum安装nginx报错. 搜了一下,很多都是修改某个配置文件的.但是在StackOverFlow的某个问题下,有人回答说修改配置文件并不是一个好的方法,虽然我采用了这个人的 ...

随机推荐

  1. 关于如何用jq定位到某个元素的索引

    在点击事件触发时候,通常如果有同样的className的列表我们都需获取它的索引来知道到底点击的是那一个 $('.info_content').mousemove(function(){ var ro ...

  2. thinkphp分页集成

    控制器: $User = M('webcase'); //  实例化 User 对象 $list = $User->order('id desc')->page($_GET['p'].', ...

  3. SVN中trunk,branches,tags用法详解【转】

    Subversion有一个很标准的目录结构,是这样的.比如项目是proj,svn地址为svn://proj/,那么标准的svn布局是 svn://proj/|+-trunk+-branches+-ta ...

  4. OpenStack安装keyston 错误BError: (pymysql.err.InternalError) (1071, u‘Specified key was too long; max key length is 767 bytes‘) [SQL: u‘\nCREATE TABLE migrate_ver

    折腾了两天的错误,BError: (pymysql.err.InternalError) (1071, u‘Specified key was too long; max key length is ...

  5. 解决因为手机设置字体大小导致h5页面在webview中变形的BUG

    首先,我们做了一个H5页面,在各种手机浏览器中打开都没问题.我们采用了rem单位进行布局,通过JS来动态计算网页的视窗宽度,动态设置html的font-size,一切都比较完美. 这时候,你自信满满的 ...

  6. Ace 在Vue中使用方法

    var Vue = require('vue/dist/vue.common.js'); document.querySelector('body').append(document.createEl ...

  7. 团队作业-Beta冲刺第三天

    这个作业属于哪个课程 <https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1> 这个作业要求在哪里 <https ...

  8. 用例重试机制rerunfailures

    安装 rerunfailures插件 pip install pytest-rerunfailures 使用: pytest --reruns  重试次数 如:pytest --reruns  2 重 ...

  9. 一个典型的flex布局,兼容性比较好

    html 代码: <body class="flex-wrap col-flex"> <header class="midCenter flex-wra ...

  10. Javascript根据指定下标或对象删除数组元素

    删除数组元素在工作中经常会用到,本文讲解一下Javascript根据下标删除数组元素的方法,需要了解的朋友可以参考下 将一下代码放在全局js文件中: Js代码 /** *删除数组指定下标或指定对象 * ...