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分钟。

最新文章

  1. 用Windows+VirtualBox搭建嵌入式Linux开发环境
  2. Java面向对象之接口
  3. HDU 4942 Game on S♂play(线段树、模拟、扩栈)
  4. JavaScript闭包演示
  5. HDU 5584 LCM Walk 数学
  6. WinFrom“动态”WebService
  7. c#之内置类型
  8. Hibernate3 第四天
  9. android — JNI注册方法说明
  10. Swift之UITabBarController 导航控制器颜色的改变
  11. 荣获MVP感想
  12. Filter、Listener 学习总结
  13. Oracle知识点总结2
  14. linux命令(51):set 指定行,直接替换并修改文件
  15. url的命名与反向解析
  16. Linux CentOS7系统探索
  17. ABP学习入门系列(六)(菜单和分页)
  18. C#-集合及特殊集合——★★哈希表集合★★
  19. windows7下的64位redis安装简介
  20. go语言基础之函数有多个返回值

热门文章

  1. CF1025C Plasticine zebra
  2. HDU4035 Maze(期望DP)
  3. IOS生成UUID
  4. MYSQL 写入emoji表情字符处理
  5. 在Ubuntu16.04安装YouCompleteMe
  6. Ubuntu 16.04下Java环境安装与配置
  7. python基础一 day11 装饰器复习
  8. 爬虫_python3_urllib
  9. shell脚本,awk数组之如何处理多个文件。
  10. 基于Passthru的NDIS开发的个人理解