PHP-FPM / FastCGI + exit()导致CPU峰值

时间:2012-02-15 17:25:36

标签: fastcgi php cherokee

我在Cherokee 1.2.101上的FastCGI中运行Archlinux / php-fpm 5.3.9的某些服务器上遇到了间歇性问题。我正在使用一个缓存插件,使用以下逻辑构建和提供静态缓存文件:

$cache_file = md5($host . $uri) . '.cache';
if( file_exists($cache_file) ) {
  $cache_file_contents = file_get_contents($cache_file)
  exit( $cache_file_contents );
}
// else build/save the $cache_file

一些进程将在exit()调用挂起的php-fpm的慢速日志中结束。当时负载高峰, 100%CPU使用率(几乎)完全到达Web服务器,PHP页面开始返回500 - 内部服务器错误。有时服务器恢复自己,其他我需要重启php-fpm和cherokee。

  • 我将PHP-FPM的FastCGI设置配置为执行

  • 即使这是一个VPS,我会暂时排除IO等待文件系统,因为缓存文件应该已经加载。我无法用vmstat

  • 进行测试
  • 我将pm.max_requests设置为500,但想知道exit()调用是否干扰了进程的循环。

  • php-fpm日志显示了很多WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers)。这似乎是php-fpm的一个正常部分,它调节了池中子进程的数量,但是

任何有关故障排除的提示都将不胜感激。以下是我发现的3件事,引发了一些危险信号:

http://www.php.net/manual/en/function.exit.php#96930

https://serverfault.com/questions/84962/php-via-fastcgi-terminated-by-calling-exit#85008

Errors when calling exit() function for fastCGI?

2 个答案:

答案 0 :(得分:1)

这可能与将输出传递给服务器(跟踪I / O)有关。您可以通过使Web服务器提供静态缓存文件来使FPM不受影响。除此之外,我建议你使用这个PHP块来减少内存/ I / O:

if (file_exists($cache_file))
{
    readfile($cache_file)
    exit;
}

请参阅readfile

如果您不想使用exit(我个人从未遇到过在PHP中使用FastCGI时遇到的问题),您应该清理代码,这样就不必使用exit,例如:您可以return或查看代码流,为什么需要使用exit并消除问题。

答案 1 :(得分:0)

我最终使用http://www.php.net/manual/en/function.exit.php

评论中引用的Pythonic异常包装方法

主要在index.php

class SystemExit extends Exception {}

try{ 
    /* Resume loading web-app */
}
catch (SystemExit $e) {}

在问题的缓存逻辑中,替换exit( $cache_file_contents );

while (@ob_end_flush());
flush();
echo $cache_file_contents;
throw new SystemExit();

这缓解了显示exit()挂起的php-fpm慢速日志。我并不完全相信它解决了潜在的问题,但它已经清理了日志文件。