前言

nginx php 超时 解决办法

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

  Nginx 504 Gateway Time-out的含义是所请求的网关没有请求到,简单来说就是没有请求到可以执行的PHP-CGI。

  解决这两个问题其实是需要综合思考的,一般来说Nginx 502 Bad Gateway和php-fpm.conf的设置有关,而Nginx 504 Gateway Time-out则是与nginx.conf的设置有关。

  而正确的设置需要考虑服务器自身的性能和访客的数量等多重因素。

  以我目前的服务器为例子CPU是奔四1.5G的,内存1GB,CENTOS的系统,访客大概是50人左右同时在线。

  但是在线的人大都需要请求PHP-CGI进行大量的信息处理,因此我将nginx.conf设置为:

  fastcgi_connect_timeout 300s;

  fastcgi_send_timeout 300s;

  fastcgi_read_timeout 300s;

  fastcgi_buffer_size 128k;

  fastcgi_buffers 8 128k;#8 128

  fastcgi_busy_buffers_size 256k;

  fastcgi_temp_file_write_size 256k;

  fastcgi_intercept_errors on;

  这里最主要的设置是前三条,即

  fastcgi_connect_timeout 300s;

  fastcgi_send_timeout 300s;

  fastcgi_read_timeout 300s;

这里规定了PHP-CGI的连接、发送和读取的时间,300秒足够用了,因此我的服务器很少出现504 Gateway Time-out这个错误。最关键的是php-fpm.conf的设置,这个会直接导致502 Bad Gateway和504 Gateway Time-out。

  

下面我们来仔细分析一下php-fpm.conf几个重要的参数:

  php-fpm.conf有两个至关重要的参数,一个是”max_children”,另一个是”request_terminate_timeout”

  我的两个设置的值一个是”40″,一个是”900″,但是这个值不是通用的,而是需要自己计算的。

  计算的方式如下:

  如果你的服务器性能足够好,且宽带资源足够充足,PHP脚本没有系循环或BUG的话你可以直接 将”request_terminate_timeout”设置成0s。0s的含义是让PHP-CGI一直执行下去而没有时间限制。而如果你做不到这一 点,也就是说你的PHP-CGI可能出现某个BUG,或者你的宽带不够充足或者其他的原因导致你的PHP-CGI能够假死那么就建议你 给”request_terminate_timeout”赋一个值,这个值可以根据你服务器的性能进行设定。一般来说性能越好你可以设置越高,20分钟 -30分钟都可以。由于我的服务器PHP脚本需要长时间运行,有的可能会超过10分钟因此我设置了900秒,这样不会导致PHP-CGI死掉而出现502 Bad gateway这个错误。

  而”max_children”这个值又是怎么计算出来的呢?这个值原则上是越大越好,php-cgi的进程多了就会处理的很快,排队的请求就 会很少。设置”max_children”也需要根据服务器的性能进行设定,一般来说一台服务器正常情况下每一个php-cgi所耗费的内存在20M左 右,因此我的”max_children”我设置成40个,20M*40=800M也就是说在峰值的时候所有PHP-CGI所耗内存在800M以内,低于 我的有效内存1Gb。而如果我的”max_children”设置的较小,比如5-10个,那么php-cgi就会“很累”,处理速度也很慢,等待的时间 也较长。如果长时间没有得到处理的请求就会出现504 Gateway Time-out这个错误,而正在处理的很累的那几个php-cgi如果遇到了问题就会出现502 Bad gateway这个错误。

fastcgi_read_timeout 300s;

其实这个小报错是之前的小故障但是也可以引发血案,所以我采取了修改php-fpm.conf 配置 nginx.conf的配置也相应设置好了所以今天介绍一下php的报错。因上大学闲暇的时候喜欢军事研究、所以本节故障为名莫斯科保卫战!

报错如下:

php-fpm5.4内容详解

现在都用php-fpm5.6 7.0 这篇5.4的php-fpm也算是之前的总结吧!

PHP5.4安装完毕后,FPM的默认配置文件于

/usr/local/php/etc/php-fpm.conf

vim /usr/local/php/etc/php-fpm.conf

php-fpm.conf配置详解 : pm = dynamic 如何控制子进程,选项有static和dynamic,默认采用dynamic;如果选择static,则由pm.max_children指定固定的子进程数。

如果选择dynamic,则由以下参数决定:
pm.max_children ,子进程最大数
pm.start_servers ,启动时的进程数
pm.min_spare_servers ,保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程
pm.max_spare_servers ,保证空闲进程数最大值,如果空闲进程大于此值,此进行清理

对于专用服务器,pm可以设置为static。 pm.max_requests 设置每个子进程重生之前服务的请求数. 对于可能存在内存泄漏的第三方模块来说是非常有用的. 如果设置为 ’0′ 则一直接受请求. 设置为500就可以了(默认0)。

将值修改为如下:pm.max_children = 32 pm.start_servers = 16 pm.min_spare_servers = 8 pm.max_spare_servers = 32 pm.max_requests = 500 之后php-fpm -t  或者 sbin目录下 出现如下:NOTICE: configuration file /usr/local/php/etc/php-fpm.conf test is successful 表示正确。

测试配置文件是否正常,没问题,杀掉当前的FPM进程/usr/local/php/sbin/php-fpm 或者 systemctl restart php-fpm 启动

有时候,运行 Nginx、PHP-CGI(php-fpm) Web服务的 Linux 服务器,突然系统负载上升,使用 top 命令查看,很多 php-cgi 进程 CPU 使用率接近100%。后来,我通过跟踪发现,这类情况的出现,跟 PHP 的 file_get_contents() 函数有着密切的关系。

  

大、中型网站中,基于 HTTP 协议的 API 接口调用,是家常便饭。PHP 程序员们喜欢使用简单便捷的 file_get_contents("http://example.com/") 函数,来获取一个 URL 的返回内容,但是,如果 http://example.com/ 这个网站响应缓慢,file_get_contents() 就会一直卡在那儿,不会超时。

  

我们知道,在 php.ini 中,有一个参数 max_execution_time 可以设置 PHP 脚本的最大执行时间,但是,在 php-cgi(php-fpm) 中,该参数不会起效。真正能够控制 PHP 脚本最大执行时间的是 php-fpm.conf 配置文件中的以下参数:

<value name="request_terminate_timeout">0s</value>

注意!新版的 php-fpm 中配置文件中格式是:

request_terminate_timeout=0s

默认值为 0 秒,也就是说,PHP 脚本会一直执行下去。这样,当所有的 php-cgi 进程都卡在 file_get_contents() 函数时,这台 Nginx+PHP 的 WebServer 已经无法再处理新的 PHP 请求了,Nginx 将给用户返回“502 Bad Gateway”。修改该参数,设置一个 PHP 脚本最大执行时间是必要的,但是,治标不治本。例如改成 30s,如果发生 file_get_contents() 获取网页内容较慢的情况,这就意味着 150 个 php-cgi 进程,每秒钟只能处理 5 个请求,WebServer 同样很难避免“502 Bad Gateway”。

  

要做到彻底解决,只能让 PHP 程序员们改掉直接使用 file_get_contents("http://example.com/") 的习惯,而是稍微修改一下,加个超时时间,用以下方式来实现 HTTP GET 请求。要是觉得麻烦,可以自行将以下代码封装成一个函数。

当然,导致 php-cgi 进程 CPU 100% 的原因不只有这一种,那么,怎么确定是 file_get_contents() 函数导致的呢?

首先, 开启 PHP <value name="request_slowlog_timeout">3s</value> 记录慢执行日志

新版 php-fpm 想来想去文件中格式是:

slowlog=/tmp/slow.log

request_slowlog_timeout=3s

日志中打印出执行慢的代码行数。

  

首先,使用 top 命令查看 CPU 使用率较高的 php-cgi 进程。

找其中一个 CPU 100% 的 php-cgi 进程的 PID,用以下命令跟踪一下:

strace -p 10747

  

如果屏幕显示:

php-cgi(php-fpm) 使用了Libevent,而Libevent 在 Linux 2.6 内核以上默认会使用 epoll I/O 模型处理 FastCGI 网络请求,而非 select/poll。在慢日志记录的代码行数中,包含 file_get_contents 以及其他函数,而 file_get_contents 等作为 Client 发起 HTTP 请求的函数使用的是 select/poll 模型,也就是说,只有 file_get_contents 等满足“TCP请求默认不超时、使用select/poll 模型、进程CPU 100%”的网络操作函数,会导致 strace -p 看到的这种情况。

简介二、

php-fpm目前主要又两个分支,分别对应于php-5.2.x的版本和php-5.3.x的版本。在5.2.x的版本中,php-fpm.conf使用的是xml格式,而在新的5.3.x版本中,则是和php.ini一样的配置风格。

在5.2.x版本中,php-fpm.conf中对于进程管理号称是有两种风格,一种是静态(static)的,一种是类似于apache风格(apache-like)的。


Process manager settings

<value name=”pm”>

Sets style of controling worker process count.

Valid values are ’static’ and ‘apache-like’

<value name=”style”>static</value>

按照文档的说明,如果pm的style采用apache-like,启动的进程数应该是和StartServers指定的一样。不过经过数次的尝 试,会发 现,实际上在这里将pm的style配置成apache-like没有起任何作用。也就是说,这里的apache-like并没有被实现。

不过,在最新的5.3.x的配套php-fpm中,apache风格的进程管理已经被实现了。

; Choose how the process manager will control the number of child processes.
; Possible Values:
; static - a fixed number (pm.max_children) of child processes;
; dynamic - the number of child processes are set dynamically based on the
; following directives:
; pm.max_children - the maximum number of children that can
; be alive at the same time.
; pm.start_servers - the number of children created on startup.
; pm.min_spare_servers - the minimum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is less than this
; number then some children will be created.
; pm.max_spare_servers - the maximum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is greater than this
; number then some children will be killed.
; Note: This value is mandatory.
;pm = dynamic
pm = static


由上面一段文字可知,对于进程的管理存在两种风格——static和dynamic。和之前的版本的进程管理其实还是一样的,只是将apache-like改成了dynamic,这样更容易理解。

如果设置成static,php-fpm进程数自始至终都是pm.max_children指定的数量,不再增加或减少。如果设置成 dynamic,则php-fpm进程数是动态的,最开始是pm.start_servers指定的数量,如果请求较多,则会自动增加, 保证空闲的进程数不小于pm.min_spare_servers,如果进程数较多,也会进行相应清理,保证多余的进程数不多于 pm.max_spare_servers。

这两种不同的进程管理方式,可以根据服务器的实际需求来进行调整。


这里先说一下涉及到这个的几个参数,他们分别是pm、pm.max_children、pm.start_servers、pm.min_spare_serverspm.max_spare_servers

pm表示使用那种方式,有两个值可以选择,就是static(静态)或者dynamic(动态)。在更老一些的版本中,dynamic被称作apache-like。这个要注意看配置文件的说明。

下面4个参数的意思分别为:
pm.max_children:静态方式下开启的php-fpm进程数量。
pm.start_servers:动态方式下的起始php-fpm进程数量。
pm.min_spare_servers:动态方式下的最小php-fpm进程数量。
pm.max_spare_servers:动态方式下的最大php-fpm进程数量。

如果dm设置为static,那么其实只有pm.max_children这个参数生效。系统会开启设置数量的php-fpm进程。如果dm设置为 dynamic,那么pm.max_children参数失效,后面3个参数生效。系统会在php-fpm运行开始 的时候启动pm.start_servers个php-fpm进程,然后根据系统的需求动态在pm.min_spare_servers和 pm.max_spare_servers之间调整php-fpm进程数。

那么,对于我们的服务器,选择哪种执行方式比较好呢?事实上,跟Apache一样,运行的PHP程序在执行完成后,或多或少会有内存泄露的问题。这也是为什么开始的时候一个php-fpm进程只占用3M左右内存,运行一段时间后就会上升到20-30M的原因了。

对于内存大的服务器(比如8G以上)来说,指定静态的max_children实际上更为妥当,因为这样不需要进行额外的进程数目控制,会提高效 率。因为频繁开关php-fpm进程也会有时滞,所以内存够大的情况下开静态效果会更好。数量也可以根据 内存/30M 得到,比如8GB内存可以设置为100,那么php-fpm耗费的内存就能控制在 2G-3G的样子。如果内存稍微小点,比如1G,那么指定静态的进程数量更加有利于服务器的稳定。这样可以保证php-fpm只获取够用的内存,将不多的 内存分配给其他应用去使用,会使系统的运行更加畅通。

对于小内存的服务器来说,比如256M内存的VPS,即使按照一个20M的内存量来算,10个php-cgi进程就将耗掉200M内存,那系统的崩 溃就应该很正常了。因此应该尽量地控制php-fpm进程的数量,大体明确其他应用占用的内存后,给它指定一个静态的小数量,会让系统更加平稳一些。或者 使用动态方式,因为动态方式会结束掉多余的进程,可以回收释放一些内存,所以推荐在内存较少的服务器或VPS上使用。具体最大数量根据 内存/20M 得到。比如说512M的VPS,建议pm.max_spare_servers设置为20。至于pm.min_spare_servers,则建议根据服 务器的负载情况来设置,比较合适的值在5~10之间。

总结:上不厌高,海不厌深

转载于:https://blog.51cto.com/lwm666/1958913

莫斯科保卫战之PHP-502 Bad Gateway相关推荐

  1. Nginx 502 bad gateway的解决方案

    Nginx 502 bad gateway的解决方案 参考文章: (1)Nginx 502 bad gateway的解决方案 (2)https://www.cnblogs.com/etiao/p/49 ...

  2. legend3---Homestead中Laravel项目502 Bad Gateway

    legend3---Homestead中Laravel项目502 Bad Gateway 一.总结 一句话总结: 用查看错误日志的方法解决错误:(/var/log/nginx/.log) 1.home ...

  3. 服务器出现 nginx 502 Bad Gateway

    发生原因1.PHP FastCGI进程数不够用 当网站并发访问巨大时,php fastcgi的进程数不有一定的保障,因为cgi是单线程多进程工作的,也就是说cgi需要处理完一个页面后再继续下一个页面. ...

  4. php-cgi导致的502 Bad Gateway错误

    spaw-fcgi控制的fastcgi进程,当然也可以用php-fpm来控制,作用都一样 设置php-cgi的进程数,在spaw-fcgi启动文件里面设置 #cd /usr/local/etc/rc. ...

  5. pomelo php,Nginx 502 Bad Gateway 自动重启shell脚本

    星期三, 2013-08-14 | Author: LeeAuthor: Lee Name: lee Email: service@i5a6.com Site: https://www.pomelol ...

  6. 深入分析Nginx 502 Bad Gateway和Nginx 504 Gateway(亲测)

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

  7. 502 bad gateway php-fm,php+nginx 上传大文件 502 Bad Gateway

    由于php每天要接收其它服务器post过来的文件 比如我在:192.168.1.147上用下面这条命令 wget http://192.168.1.148/upload.php --post-file ...

  8. lnmp一键包502 Bad Gateway解决方法

    使用LNmp有一段时间了,可是在流量大的时候,有时会莫名其妙的出现Nginx 502 Bad Gateway,不是php-fpm死掉了,就是nginx死掉了,网站多的时候根本没空每天一个个检查,往往是 ...

  9. 502 Bad Gateway - Registered endpoint failed to handle the request

    2017-08-07 Greeting from China! I have one question regarding error message "" in SAP clou ...

最新文章

  1. ubuntu常用翻译工具stardict
  2. MS SQLSERVER通用存储过程分页
  3. java 钉钉获取用户信息,JAVA maven项目如何使用钉钉SDK来获取token、用户
  4. 进程返回linux系统编程之管道(二):管道读写规则和Pipe Capacity、PIPE_BUF
  5. md发布test-1 md发布test-1md发布test-1md发布test-1md发布test-1md发布test-1md发布test-1md发布test-1md发布test-1md发布test-
  6. Linux中nginx安装基础教程
  7. 暮光之城3蓝光BD高清下载
  8. 使用U盘升级到win10系统
  9. matlab 控制声卡,用MATLAB和声卡实现T型波信号发生器的设计方法
  10. android服务端与客户端
  11. mysql左连接查询慢
  12. 5G学习之路——认识基站、扇区、小区
  13. Every Pixel Matters: Center-aware Feature Alignment for Domain Adaptive Object Detector
  14. 中国自主建成世界口径最大的大视场望远镜
  15. 【小白必读】机器学习入门须知
  16. golang多版本管理工具g使用(windows)
  17. ThinkPHP5 集成使用 Layui 穿梭框(transfer)控件
  18. networkx网络拓扑节点图和树,python
  19. Tensorflow基础4:run()函数
  20. 前端面试那些你必须手撕的代码

热门文章

  1. 企业级 SpringBoot 教程 (十二)springboot集成apidoc
  2. The Beam Model:Stream Tables翻译(上)
  3. [持续更新][小工具]计算器
  4. HTML5与CSS3实战指南读书笔记之一些可能会有用的东西
  5. 剑指offer 二进制1中的个数
  6. windows2008下VS2008发布失败
  7. 搜索引擎优化(独立阐述)
  8. CentOS7 升级 Git 版本
  9. Linux内核移植之二:Kconfig分析
  10. ROM,RAM,DRAM,SDRAM,SRAM