我有一些代码将文件复制到临时位置,稍后将其包含在 zip 文件中。
我已经将源文件存储在本地缓存目录中,并且还存储了原始文件的 SHA1 哈希值。有问题的文件是 .png 图像,大小从几 kb 到大约 500kb 不等。
我的问题是在高服务器负载下,副本会间歇性地失败。在检查我的日志后,我发现即使源位置中存在一个健康的文件,目标位置也包含一个零字节的文件。
因此,为了弄清楚发生了什么并提高可靠性,我对目标文件实施了 SHA1 检查,这样如果失败,我可以使用 shell 重试副本。
99.9% 的时间,文件复制没有问题。有时,第一次复制失败,但第二次尝试成功。在少数情况下(大约 2,500 分之一;并且始终处于高服务器负载),两个副本都会失败。在几乎所有这些情况下,目标文件的 SHA1da39a3ee5e6b4b0d3255bfef95601890afd80709
与空文件一致。
在所有情况下,脚本都会继续,并且创建的 zip 包含一个空图像文件。Nginx、PHP 或 PHP-FPM 错误日志中没有任何内容表明存在任何问题。重试时,该脚本将成功复制相同的文件。
我的堆栈是 Debian Squeeze,在 Amazon EBS 支持的 AMI 上带有 .deb PHP 5.4/PHP 5.4 FPM 包和 Nginx 1.2.6。文件系统是 XFS,我没有使用 APC 或其他缓存。在服务器负载 > 每秒 500 次命中时,该问题是一致且可复制的。
我找不到任何可以解释这种行为的已知问题的文档。谁能提供有关可能导致此问题的原因的任何见解,或者就如何更可靠地将图像文件复制到临时位置进行压缩提供建议?
作为参考,这里是用于复制/重新复制文件的代码的摘录。
$copy = copy ($cacheFile, $outputFile);
if ($copy && file_exists($outputFile) && sha1_file($outputFile) !== $storedHash) {
// Custom function to log debug messages
dbug(array($cacheFile, sha1_file($cacheFile),
$storedHash, $outputFile,
file_exists($outputFile), filesize($outputFile)),
'Corrupt Image File Copy from Cache 1 (native)');
// Try with exec
exec ("cp " . $cacheFile . " " . $outputFile);
if (file_exists($outputFile) && sha1_file($outputFile) !== $storedHash)
dbug(array($cacheFile, sha1_file($cacheFile),
$storedHash, $outputFile,
file_exists($outputFile), filesize($outputFile)),
'Corrupt Image File Copy from Cache 2 (shell exec)');
}