PHP-FPM 在完成繁重工作时拥有太多用户时崩溃

2022-08-30 17:54:02

我有一个运行Apache / 2.2.22(Debian),PHP 5.6.17作为FPM和MySQL 5.6.25的服务器。

该项目使用名为Redaxo的CMS运行(我不认为它那么重要,但我还是会告诉你)。在Redaxo中,有些功能需要一些时间(例如,删除缓存并重建缓存需要1-2分钟)。在这段时间里,当其他用户访问网站时,FPM崩溃了,我必须多次重新加载页面,直到服务器错误消失并且该过程完成。500 Internal Server Error

我注意到,只有当太多用户同时在网站上并且仅在完成繁重操作时,才会发生这种情况。

10个用户同时上网=没有问题
10个用户同时上网,而缓存删除=500个错误给大家。

我通过禁止除我以外的所有人的网站来检查这一点(.htaccess deny/allow with ip)。然后我做了繁重的手术,没有问题。一旦多个人再次出现在网站上,问题就再次出现。

它可能是什么?你们需要我从我这里获取什么信息?

这些值在php-fpm.conf

[global]
pid = /run/php5-fpm.pid
error_log = /var/log/php5-fpm.log
emergency_restart_threshold = 0
include=/etc/php5/fpm/pool.d/*.conf

这些值在特定于项目中设置(未注释)fpm.conf

[projectname]
user = projectname
group = projectname

listen = /var/run/php5-fpm-projectname.sock
listen.owner = projectname
listen.group = projectname
listen.mode = 0660

pm = dynamic
pm.max_children = 150
pm.start_servers = 10
pm.min_spare_servers = 10
pm.max_spare_servers = 30

chdir = /

php_value[upload_max_filesize] = 128M
php_value[max_post_size] = 128M
php_value[max_execution_time] = 180
php_value[memory_limit] = 256M

如果脚本有帮助,失败时它对MySQL和文件创建有很大帮助吗?但它很大,所以我不确定我是否应该在这里发布它?或者,如果这甚至是问题所在?

apache错误日志显示

[Tue Feb 09 10:54:01 2016] [error] [client {IP}] (104)Connection reset by peer: FastCGI: comm with server "/fcgi-bin-php5-fpm-projectnmae" aborted: read failed
[Tue Feb 09 10:54:01 2016] [error] [client {IP}] FastCGI: incomplete headers (0 bytes) received from server "/fcgi-bin-php5-fpm-projectnmae"

或者这个

[Tue Feb 09 11:00:46 2016] [error] [client {IP}] FastCGI: incomplete headers (0 bytes) received from server "/fcgi-bin-php5-fpm-projectname"
[Tue Feb 09 11:00:48 2016] [error] [client {IP}] (104)Connection reset by peer: FastCGI: comm with server "/fcgi-bin-php5-fpm-projectname" aborted: read failed

下面是这样说的。当然,总是不同的时间fpm-log

[10-Feb-2016 09:40:59] WARNING: [pool projectname] child 10970 exited on signal 7 (SIGBUS) after 50.186611 seconds from start
[10-Feb-2016 09:40:59] NOTICE: [pool projectname] child 11092 started

有时其中有这样的警告

[09-Feb-2016 11:00:41] WARNING: [pool projectname] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 8 children, there are 0 idle, and 6 total children
[09-Feb-2016 11:00:42] WARNING: [pool projectname] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 16 children, there are 0 idle, and 7 total children

以下是一些更多调试信息

[18-Feb-2016 17:42:01] WARNING: [pool projectname] child 9088 exited on signal 7 (SIGBUS) after 70.130564 seconds from start
[18-Feb-2016 17:42:01] NOTICE: [pool projectname] child 9205 started
[18-Feb-2016 17:43:55] WARNING: [pool projectname] child 9099 said into stderr: "NOTICE: PHP message: PHP Notice:  Undefined offset: 1181 in /var/www/projectname/htdocs/redaxo/include/classes/class.ooarticle.inc.php on line 44"
[18-Feb-2016 17:43:55] WARNING: [pool projectname] child 9099 said into stderr: "NOTICE: PHP message: PHP Warning:  Invalid argument supplied for foreach() in /var/www/projectname/htdocs/redaxo/include/classes/class.ooredaxo.inc.php on line 134"
[18-Feb-2016 17:43:55] WARNING: [pool projectname] child 9099 exited on signal 7 (SIGBUS) after 183.838886 seconds from start
[18-Feb-2016 17:43:55] NOTICE: [pool projectname] child 9330 started
[18-Feb-2016 17:44:00] WARNING: [pool projectname] child 9101 exited on signal 7 (SIGBUS) after 188.987954 seconds from start
[18-Feb-2016 17:44:00] NOTICE: [pool projectname] child 9336 started

答案 1

这可能只是MySQL服务器某些锁定问题的影响。

您必须在延迟期间连接到MySQL主机。

  • 如果无法连接,则表示 MySQL 服务器或用户允许的并发连接数不足

  • 如果可以连接,则必须查看mysql命令“show processlist”返回的内容。现在您有 2 个选择:

    • 许多“等待查询缓存锁定”:这将要求您更改一些MySQL服务器配置。(这可能是由过大的查询缓存引起的)

    • 您有一个请求,该请求需要所有资源,您必须对其进行优化。


答案 2

除非你有足够的RAM可用(比如超过16GB可用),否则我建议你资源耗尽,这会导致500错误。

您的配置是说,您最多可以生成150个PHP-FPM进程,每个进程可以使用256MB的内存 - 仅此一项就可以使PHP-FPM服务器使用超过38GB的内存,如果不可用,它将导致500错误。

计算每个服务器可以使用的内存,然后正确设置它。此 CMS 是否需要高达 256MB 的内存?它能否以更少的内存(如 32MB)运行?如果MySQL,Apache和Nginx位于同一台服务器中,请分开每个服务器将使用的内存,然后为 和 设置适当的值。pm.max_childrenphp_value[memory_limit]

请注意,资源缺乏是系统范围的,因此如果您的PHP进程使用了所有可用内存,MySQL最终可能会因资源耗尽而崩溃(这可能是找不到记录的原因)。

如果你能说出你有多少可用内存,我可以帮助你配置这些数字。

在发出缓存删除之前,了解有多少内存可用以及运行时有多少可用内存也是很好的 - 它可能确实使用了太多的内存并窒息了其他进程(如果它使用PHP-CLI,它可能没有内存限制)。


推荐