2

ファイルを一時的な場所にコピーし、後でzipファイルに含めるコードがあります。

ソース ファイルは既にローカル キャッシュ ディレクトリに保存されており、元のファイルの SHA1 ハッシュも保存されています。問題のファイルは .png 画像で、数 kb から約 500 kb の範囲です。

私の問題は、サーバーの負荷が高いと、コピーが断続的に失敗することです。ログを調べると、ソースの場所に正常なファイルが存在する場合でも、宛先にはゼロ バイトのファイルが含まれていることがわかります。

そこで、何が起こっているのかを突き止めて信頼性を高めるために、コピー先ファイルの SHA1 チェックを実装しました。失敗した場合は、シェルを使用してコピーを再試行できます。

99.9% の確率で、ファイルは問題なくコピーされます。場合によっては、最初のコピーは失敗しますが、2 回目の試行は成功します。いくつかのケース (約 2,500 分の 1 で、常にサーバーの負荷が高い) では、両方のコピーが失敗します。これらのほとんどすべてのケースで、宛先ファイルの SHA1 はda39a3ee5e6b4b0d3255bfef95601890afd80709空のファイルと一致しています。

どのような場合でも、スクリプトは続行され、作成された zip には空のイメージ ファイルが含まれます。Nginx、PHP、または PHP-FPM のエラー ログには、問題を示すものは何もありません。再試行すると、スクリプトは同じファイルを正常にコピーします。

私のスタックは、.deb PHP 5.4/PHP 5.4 FPM パッケージを使用した Debian Squeeze と、Amazon EBS でサポートされた AMI 上の Nginx 1.2.6 です。ファイル システムは XFS で、APC やその他のキャッシュは使用していません。この問題は一貫しており、1 秒あたり 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)');
}
4

0 に答える 0