最近我的php应用程序经常无法使用。它每天发生几次。
在php-fpm错误日志中,我看到以下消息:
[23-Mar-2015 16:49:42] NOTICE: fpm is running, pid 8038
[23-Mar-2015 16:49:43] NOTICE: ready to handle connections
[23-Mar-2015 16:49:47] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 98 idle, and 105 total children
[23-Mar-2015 16:49:57] WARNING: [pool www] child 8132 exited on signal 11 (SIGSEGV) after 13.640528 seconds from start
[23-Mar-2015 16:49:57] NOTICE: [pool www] child 8151 started
[23-Mar-2015 16:49:59] WARNING: [pool www] child 8091 exited on signal 11 (SIGSEGV) after 16.331350 seconds from start
[23-Mar-2015 16:49:59] NOTICE: [pool www] child 8155 started
[24-Mar-2015 09:38:01] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 0 idle, and 15 total children
[24-Mar-2015 09:38:01] ERROR: [pool ] no free scoreboard slot
[24-Mar-2015 17:00:39] NOTICE: [pool www] child 27622 started
[24-Mar-2015 17:00:51] WARNING: [pool www] child 27482 exited on signal 11 (SIGSEGV) after 230.000581 seconds from start
[24-Mar-2015 17:00:51] NOTICE: [pool www] child 27623 started
[24-Mar-2015 17:01:07] WARNING: [pool www] child 27522 exited on signal 11 (SIGSEGV) after 246.737464 seconds from start
[24-Mar-2015 17:01:07] ERROR: [pool ] no free scoreboard slot
[24-Mar-2015 17:01:13] WARNING: [pool www] child 27538 exited on signal 11 (SIGSEGV) after 252.268165 seconds from start
[24-Mar-2015 17:01:13] ERROR: [pool ] no free scoreboard slot
执行service php-fpm reload
暂时解决问题,并在一段时间后再次提升。
根据nginx的访问日志,每分钟最多有1000个请求,大约600个请求被传递给php-fpm(其他是静态文件)。看起来并不重。
服务器环境:
php-fpm配置:
pm = dynamic
pm.max_children = 100
pm.start_servers = 100
pm.min_spare_servers = 100
pm.max_spare_servers = 1000
pm.max_requests = 500
我试过pm = static并更改了其他参数,但都没有工作。
作为临时解决方案,我编写了一个shell脚本来定期检查服务可用性。如果没有,请重新加载php-fpm。
但我怎么能完全解决问题?
答案 0 :(得分:1)
最后,在我修改了一行试图从MySQL获取表的所有记录(有时高达10K)的可怕代码之后问题就消失了。
我检查了nginx的访问日志,并惊讶地发现许多api请求产生了500个响应代码。
经过一番挖掘,我发现它是由一行代码试图从MySQL获取表的所有记录引起的。没有多条记录时没关系,但当记录超过10K时,请求以500内部错误结束。
修改了可怕的代码之后,不再向该api发出请求500,而php-fpm错误也会消失。
2015-12-28更新:
我认为打破整个应用程序的真正原因是对执行错误的api的请求占用了太多内存,并且需要太多的执行时间。
因此,php-fpm工作池充满了这样的请求,因此没有工作人员来处理其他请求。所以整个应用程序都崩溃了。
这些请求因500而失败的原因可能是内存耗尽,或执行时间超过php.ini中指定的max_execution_time
。
如果你遇到这个问题,检查你的访问日志(nginx或php-fpm),并尝试找到总是占用太多内存/时间的请求(内存使用情况只能在php-fpm' s访问日志),或始终失败的请求。然后检查问题是否是由这些请求引起的。