莫斯科保卫战之PHP-502 Bad Gateway

前言

其实这个小报错是之前的小故障但是也可以引发血案,所以我采取了修改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 看到的这种情况。

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

时间: 2024-10-11 02:35:04

莫斯科保卫战之PHP-502 Bad Gateway的相关文章

LNMP : 502 Bad Gateway 解决小记,真正的原因

网站搬迁到新的服务器,原先一直都是LAMP,现在改为LNMP. 将重写文件 htaccess改成 nginx的 conf.放到了网站,可只能打开首页,其他重写页面一打开都是不停的加载. 加载等待几十分钟之后会提示 502 Bad Gateway! -- 后来逐一排查,排查到重写规则是没有问题,程序是没有问题,原因出在了数据库连接. -- 排查到最后的原因居然是数据库连接地址 写成了127.0.0.1,改成localhost 之后一切正常. 写到这里 LNMP 网站终于搬迁完毕,原因出人意外. b

nginx 502 Bad Gateway的解决方法总结

昨天自己的机器老提示502 Bad Gateway错误提示,下面小编来给大家总结关于nginx出现502 Bad Gateway的解决方法,有碰到此类问题的朋友可参考. 发生原因 1.PHP FastCGI进程数不够用 当网站并发访问巨大时,php fastcgi的进程数不有一定的保障,因为cgi是单线程多进程工作的,也就是说cgi需要处理完一个页面后再继续下一个页面.如果进程数不够,当访问巨大的时候,cgi按排队处理之前的请求,之后的请求只有被放弃.这个时候nginx就会不时的出现502错误.

Nginx 502 bad gateway错误解决思路

当网站打开遇到Nginx 502 bad gateway的错误,造成这种错误的原因有很多,下面分别解析nginx常见的502错误. 1.nginx配置文件错误 因为nginx找不到php-fpm了,所以报错,一般是fastcgi_pass后面的路径配置错误了,后面可以是socket或者是ip:port 解决方案: [[email protected] ~]# vim/usr/local/nginx/conf/vhosts/www.conf server {    listen 80;    se

Nginx 502 Bad Gateway 错误的原因及解决方法

http://my.oschina.net/zhouyuan/blog/118708 刚才在调试程序的时候,居然服务器502错误,昨天晚上也发生了,好像我没有做非常规的操作. 然后网上寻找了下答案, 把一些原因及解决方法汇总一下,以防生产环境下的502  会有好多种情况出现502错误,下面我们分情况来说一下. 一.fastcgi缓冲区设置过小 出现错误,首先要查找nginx的日志文件,目录为/var/log/nginx,在日志中发现了如下错误. 2013/01/17 13:33:47 [erro

Nginx + php-fpm 执行 PHP 脚本超时 报错 502 Bad Gateway 的解决办法

上周写好的发送邮件的计划任务只发送了一部分,检查计划任务日志,发现 502 Bad Gateway 的错误(已经在脚本中设置了 set_time_limit(0)). 后来在网上查找资料,可以通过以下设置来解决脚本超时导致 502 Bad Gateway 的问题(Nginx + php-fpm,CentOs 系统): ① Nginx 设置 修改 nginx.conf: fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_r

502 Bad Gateway

502 Bad Gateway The proxy server received an invalid response from an upstream server. Sorry for the inconvenience.Please report this message and include the following information to us.Thank you very much! URL: http://y.baidu.com/index.html Server:

502 Bad Gateway深究

早上收到502报警,设置的报警规则是502错误两分钟超过500就报警. 排障流程: 日志分析系统报障-->查看日志系统日志-->nginx错误日志-->php错误日志-->php-fpm.log日志 在日志分析系统里面看到产生502报警的机器只有一台xxx.xxx.xxx.170,客户端IP也只有一个,说明不是大规模故障. 连接到170服务器查看nginx错误日志,看到Connection reset by peer,连接被对方重置,说明php关掉了这个连接 2016/12/29

502 Bad Gateway(PHP的角度来分析)

第一点: request_terminate_timeout引起的资源问题 request_terminate_timeout的值如果设置为0或者过长的时间,可能会引起file_get_contents的资源问题.如果file_get_contents请求的远程资源如果反应过慢,file_get_contents就会一直卡在那里不会超时.我们知道php.ini 里面max_execution_time 可以设置 PHP 脚本的最大执行时间,但是,在 php-cgi(php-fpm) 中,该参数不

502 Bad Gateway nginx 解决

打开 /usr/local/php/etc/php-fpm.conf 调大以下两个参数(根据服务器实际情况,过大也不行) <value name="max_children">5120</value> <value name="max_requests">600</value>502 Bad Gateway nginx 解决