Nginx + PHP-FPMでサーバーを実行しています。その上に PHP スクリプトがあり、HTTP 要求を取得し、DB (MongoDB) から取得した大量のデータ セット (100K レコードとします) で応答します。
応答はレコードごとに形成され、各レコードの後に改行が続き、クライアントにエコーされ、すぐにフラッシュされます。
ここでのクライアントは、同様のプラットフォーム上の別のサーバーです。HTTP リクエストは CURLOPT_FILE が設定された CURL によって行われるため、すべてのデータをメモリに保存しようとはしません。
応答を含むファイル内の一部の行が破損します (多数の NUL バイトが含まれ、その後に通常のデータが続きます)。これは、継ぎ目のないランダムな応答行で発生し、1K の応答行で約 1 回発生します。
解決策を見つけることができるように、少なくともここで何が間違っている可能性があるかを誰かが教えてくれたら幸いです。
このコードは応答を送信します。
set_time_limit(self::TIME_LIMIT);
header('Content-Type: text/plain');
//clear the buffers
if (ob_get_level())
{
while (@ob_end_flush());
}
findAndProcessRecord($this->request, function(RecordClass $record) {
echo $this->packRecord($record) . "\n";
flush();
});
packRecord()
メソッドは基本的にデータを暗号化しbase64_encode()
てからそれを
このコードは、CURL によってリクエストを作成します。
$url = $project->apiUrl . '?' . http_build_query($requestParams);
$responseFile = fopen('php://temp', 'w+');
ini_set('memory_limit', self::MEM_LIMIT . 'M');
set_time_limit(self::TIME_LIMIT);
$curlResource = curl_init($url);
curl_setopt_array(
$curlResource,
[
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_TIMEOUT => self::CURL_TIMEOUT,
CURLOPT_RETURNTRANSFER => false,
CURLOPT_FILE => $responseFile,
CURLOPT_HEADER => false,
]
);
curl_exec($curlResource);
に$responseFile
は、開いているファイルのハンドルがあり、内部に応答があります。次に、このハンドルを使用して反復子を作成し、応答行をトラバースします。