0

在 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 使用率(几乎)完全流向网络服务器,PHP 页面开始返回 500 - Internal Server 错误。有时服务器会自行恢复,其他的我需要重新启动 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

为 fastCGI 调用 exit() 函数时出错?

4

2 回答 2

1

这可能与将输出传递到服务器(也跟踪 I/O)有关。您可以通过让您的网络服务器为静态缓存文件提供服务来避免 FPM。除此之外,我建议你使用这个 PHP 块来减少内存/I/O:

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

readfile

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

于 2012-02-15T17:32:41.507 回答
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();

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

于 2012-02-21T20:35:00.737 回答